首页 > 解决方案 > 从域服务和应用层访问 SignalR

问题描述

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

两个问题:

  1. 为了能够同时使用HubinDomain.Core和 App 项目,我应该如何将它们全部连接起来?如果我在 App 层用 null 模式定义接口,我可以在Web.Core. 但是我不能在域服务中使用它(例如EventBus)。

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

标签: signalr-hubaspnetboilerplateasp.net-core-signalr

解决方案


  1. 为了能够同时使用HubinDomain.Core和 App 项目,我应该如何将它们全部连接起来?

领域层:

  • 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. 我可以将整个 SignalR 集线器移动到一个新模块并从应用程序、域和 Web 层引用它吗?

您可以,但是包含 SignalR 集线器(以及因此您的应用程序和域层)的新模块将依赖于Microsoft.AspNetCore.SignalR,这依赖于Microsoft.AspNetCore.Http.Connections. 域层不应该依赖Http.


推荐阅读