Access SignalR from domain services and application layer

。_饼干妹妹 提交于 2021-02-11 13:32:53

问题


This is directly related to calling a SignalR Hub from the Application Service Layer in ASP.NET Boilerplate .NET Core version. As per the solution, SignalR hub implementation should be done in Web layer. But the dependency structure of the projects are like:

  • App depends on Domain.Core
  • Web.Core depends on App
  • Web.Host depends on Web.Core

Two questions:

  1. To be able to use the Hub in both Domain.Core and App projects, how should I wire it all up? If I define the interface in App layer with a null pattern, I can implement it in Web.Core. But then I can't use it in domain services (e.g. EventBus).

  2. Can I move entire SignalR hub to a new module and reference it from App, Domain and Web layers?


回答1:


  1. To be able to use the Hub in both Domain.Core and App projects, how should I wire it all up?

Domain layer:

  • IMyNotifier interface
  • NullMyNotifier null implementation
public interface IMyNotifier
{
    Task SendMessage(IUserIdentifier user, string message);
}

public class NullMyNotifier : IMyNotifier
{
    public static NullMyNotifier Instance { get; } = new NullMyNotifier();

    private NullMyNotifier()
    {
    }

    public Task SendMessage(IUserIdentifier user, string message)
    {
        return Task.FromResult(0);
    }
}

Web layer:

  • SignalR hub implementation, e.g. MyChatHub
  • SignalRMyNotifier concrete implementation
public class SignalRMyNotifier : IMyNotifier, ITransientDependency
{
    private readonly IOnlineClientManager _onlineClientManager;
    private readonly IHubContext<MyChatHub> _hubContext;

    public SignalRMyNotifier(
        IOnlineClientManager onlineClientManager,
        IHubContext<MyChatHub> hubContext)
    {
        _onlineClientManager = onlineClientManager;
        _hubContext = hubContext;
    }

    public async Task SendMessage(IUserIdentifier user, string message)
    {
        var onlineClients = _onlineClientManager.GetAllByUserId(user);
        foreach (var onlineClient in onlineClients)
        {
            var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
            await signalRClient.SendAsync("getMessage", message);
        }
    }
}

Usage, in any layer that references Domain layer:

public class MyDomainService : DomainService, IMyManager
{
    public IMyNotifier MyNotifier { get; set; }

    public MyDomainService()
    {
        MyNotifier = NullMyNotifier.Instance;
    }

    public async Task DoSomething()
    {
        // Do something
        // ...

        var hostAdmin = new UserIdentifier(null, 1);
        var message = "Something done";
        await MyNotifier.SendMessage(hostAdmin, message);
    }
}
  1. Can I move entire SignalR hub to a new module and reference it from App, Domain and Web layers?

You can, but the new module that contains the SignalR hub (and thus your App and Domain layers) would depend on Microsoft.AspNetCore.SignalR, which depends on Microsoft.AspNetCore.Http.Connections. Domain layer should not depend on Http.



来源:https://stackoverflow.com/questions/59483789/access-signalr-from-domain-services-and-application-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!