从领域服务和应用层访问 SignalR

Access SignalR from domain services and application layer

这与 ASP.NET Boilerplate .NET Core 版本中的 直接相关。根据解决方案,SignalR 集线器实现应在 Web 层完成。但是项目的依赖结构是这样的:

两个问题:

  1. 为了能够在Domain.Core和App项目中使用Hub,我应该如何连接它们?如果我在App层用空模式定义接口,我可以在Web.Core中实现它。但是我不能在域服务中使用它(例如 EventBus)。

  2. 我可以将整个 SignalR 中心移动到一个新模块并从应用程序、域和 Web 层引用它吗?

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

领域层:

  • IMyNotifier界面
  • NullMyNotifier 空实现
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);
    }
}

网络层:

  • SignalR 集线器实现,例如MyChatHub
  • SignalRMyNotifier具体实现
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);
        }
    }
}

用法,在任何引用域层的层中:

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?

可以,但是包含 SignalR 集线器(以及您的 App 和 Domain 层)的新模块将取决于 Microsoft.AspNetCore.SignalR,而后者又取决于 Microsoft.AspNetCore.Http.Connections。域层不应依赖于 Http.