ハブが配置されているプロジェクトの外部のメソッドからSignalRHubContextを介してメッセージを送信します

Dec 08 2020

API、サービス、データの各レイヤーがすべて同じソリューションの別々のプロジェクトにあるWebAPIプロジェクトがあります。サービスプロジェクトのメソッドの一部として、APIプロジェクトのハブの接続されたクライアントにメッセージを送信したいと思います。これまでのところ、私が見つけたすべての例では、すべてが1つのプロジェクトに含まれており、ハブを介してメッセージを送信する例としてコントローラーを使用しています。

依存性注入(Autofac)を試しましたが、MessageHubへの参照を取得できません。

[HubName("messages")]
public class MessageHub : Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}

インジェクションの私の試みはここで見ることができます:Autofacを使用してSignalRIHubContextをサービスレイヤーにインジェクトします

回答

1 AlexanderI. Dec 08 2020 at 04:41

このオプションを確認してください:

  1. サービス(またはより適切なドメイン)レイヤープロジェクトで汎用ハブインターフェイスを定義します。のようなものIMessageBroker
  2. プレゼンテーション層(WebAPI)プロジェクト内で、このインターフェイスを実装しIConnectionManager、HubContextの取得に使用します。
  3. プレゼンテーション層のIoCコンテナ(Autofac)にインターフェイスを登録します
  4. AppService内にインターフェースを挿入します

擬似コード:

ドメインレイヤー:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

サービスレイヤー:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

    public NotificationService(IMessageBroker messageBroker)
    {
        _messageBroker = messageBroker;
    }

    public void RunNotification(string message)
    {
        _messageBroker.ShowNewMessage(message);
    }
}

プレゼンテーション層:

[HubName("messages")]
public class MessageHub: Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}


public class MessageBroker: IMessageBroker
{
    private readonly IConnectionManager _connectionManager;

    public MessageBroker(IConnectionManager connectionManager)
    {
        _connectionManager = connectionManager;
    }

    public void ShowNewMessage(string message)
    {
        var hub = _connectionManager.GetHubContext<MessageHub>();
        // Use Hub Context and send message
    }
}

Autofac登録(プレゼンテーション層):

// Register Hubs
builder.RegisterHubs(Assembly.GetExecutingAssembly());

// Register Autofac resolver into container to be set into HubConfiguration later
builder.RegisterType<AutofacDependencyResolver>().As<IDependencyResolver>().SingleInstance();

// Register ConnectionManager as IConnectionManager so that you can get hub context via IConnectionManager injected to your service
builder.RegisterType<ConnectionManager>().As<IConnectionManager>().SingleInstance();

// Register interface
builder.RegisterType<MessageBroker>().As<IMessageBroker>();

同様のSOトピックもここにあります。