Senden Sie Nachrichten über SignalR HubContext von einer Methode in einem Projekt außerhalb von Hubs

Dec 08 2020

Ich habe ein WebAPI-Projekt, in dem sich die API-, Service- und Datenebenen in separaten Projekten derselben Lösung befinden. Als Teil einer Methode in meinem Service-Projekt möchte ich eine Nachricht an die verbundenen Clients eines Hubs im API-Projekt senden. Bisher haben alle Beispiele, die ich gefunden habe, alles in einem einzigen Projekt und verwenden einen Controller als Beispiel für das Senden einer Nachricht über einen Hub.

Ich habe die Abhängigkeitsinjektion (Autofac) versucht, kann jedoch keinen Verweis auf den MessageHub erhalten.

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

Mein Versuch, zu injizieren, ist hier zu sehen: Injizieren Sie SignalR IHubContext mit Autofac in die Service-Schicht

Antworten

1 AlexanderI. Dec 08 2020 at 04:41

Bitte überprüfen Sie diese Option:

  1. Definieren Sie die generische Hub-Schnittstelle in Ihrem Service (oder besser Domain) Layer-Projekt. So etwas wie IMessageBroker.
  2. Implementieren Sie diese Schnittstelle in Ihrem WebAPI-Projekt (Presentation Layer) und verwenden Sie sie IConnectionManagerzum Abrufen von HubContext.
  3. Registrieren Sie die Schnittstelle in einem IoC-Container (Autofac) in der Präsentationsschicht
  4. Injizieren Sie die Schnittstelle in App Service

Pseudocode:

Domänenschicht:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

Serviceschicht:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

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

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

Präsentationsfolie:

[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-Registrierung (Präsentationsschicht):

// 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>();

Ein ähnliches SO-Thema finden Sie hier .