【问题标题】:Access SignalR from domain services and application layer从域服务和应用层访问 SignalR
【发布时间】:2020-04-16 10:08:52
【问题描述】:

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

  • 应用依赖于Domain.Core
  • Web.Core 依赖App
  • Web.Host 取决于 Web.Core

两个问题:

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

  2. 我能否将整个 SignalR 集线器移动到新模块并从应用、域和 Web 层引用它?

【问题讨论】:

    标签: signalr-hub aspnetboilerplate asp.net-core-signalr


    【解决方案1】:
    1. 为了能够在 Domain.Core 和 App 项目中使用 Hub,我应该如何将其全部连接起来?

    领域层:

    • IMyNotifier接口
    • NullMyNotifier null 实现
    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.SignalR 又依赖于 Microsoft.AspNetCore.Http.Connections。域层不应依赖Http

    【讨论】:

      猜你喜欢
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 2015-02-21
      • 2011-02-11
      • 1970-01-01
      • 2010-09-25
      相关资源
      最近更新 更多