从领域服务和应用层访问 SignalR
Access SignalR from domain services and application layer
这与 ASP.NET Boilerplate .NET Core 版本中的 直接相关。根据解决方案,SignalR 集线器实现应在 Web 层完成。但是项目的依赖结构是这样的:
- 应用依赖于
Domain.Core
Web.Core
取决于 App
Web.Host
取决于 Web.Core
两个问题:
为了能够在Domain.Core
和App项目中使用Hub
,我应该如何连接它们?如果我在App层用空模式定义接口,我可以在Web.Core
中实现它。但是我不能在域服务中使用它(例如 EventBus
)。
我可以将整个 SignalR 中心移动到一个新模块并从应用程序、域和 Web 层引用它吗?
- 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);
}
}
- 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
.
这与 ASP.NET Boilerplate .NET Core 版本中的
- 应用依赖于
Domain.Core
Web.Core
取决于 AppWeb.Host
取决于Web.Core
两个问题:
为了能够在
Domain.Core
和App项目中使用Hub
,我应该如何连接它们?如果我在App层用空模式定义接口,我可以在Web.Core
中实现它。但是我不能在域服务中使用它(例如EventBus
)。我可以将整个 SignalR 中心移动到一个新模块并从应用程序、域和 Web 层引用它吗?
- To be able to use the
Hub
in bothDomain.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);
}
}
- 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
.