Envoyer des messages via SignalR HubContext à partir de la méthode du projet en dehors de l'emplacement des concentrateurs

Dec 08 2020

J'ai un projet WebAPI où les couches API, Service et Data sont toutes dans des projets séparés de la même solution. Dans le cadre d'une méthode dans mon projet Service, je souhaite envoyer un message aux clients connectés d'un hub dans le projet API. Jusqu'à présent, tous les exemples que j'ai trouvés ont tout dans un seul projet et utilisent un contrôleur comme exemple d'envoi d'un message via un hub.

J'ai essayé l'injection de dépendances (Autofac), mais je ne parviens pas à obtenir une référence au MessageHub.

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

Ma tentative d'injection peut être vue ici: Injecter SignalR IHubContext dans la couche de service avec Autofac

Réponses

1 AlexanderI. Dec 08 2020 at 04:41

Veuillez revoir cette option:

  1. Définissez une interface de concentrateur générique dans votre projet de couche de service (ou mieux de domaine). Quelque chose comme IMessageBroker.
  2. Dans votre projet de couche de présentation (WebAPI), implémentez cette interface et utilisez-la IConnectionManagerpour la récupération HubContext.
  3. Enregistrez l'interface dans un conteneur IoC (Autofac) dans la couche de présentation
  4. Injectez l'interface dans App Service

Pseudo code:

Couche de domaine:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

Couche de service:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

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

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

Couche de présentation:

[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
    }
}

Enregistrement Autofac (couche de présentation):

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

Un sujet SO similaire est également disponible ici .