问题描述
我有一个WebAPI项目,其中API,服务和数据层都在同一解决方案的单独项目中.作为服务项目中方法的一部分,我想向API项目中集线器的已连接客户端发送消息.到目前为止,我发现的所有示例都在一个项目中包含所有内容,并使用控制器作为通过集线器发送消息的示例.
I have a WebAPI project where the API, Service and Data layers are all in separate projects of the same solution. As part of a method in my Service project, I want to send a message to the connected clients of a hub in the API project. So far all of the examples I have found have everything in a single project and use a controller as the example sending a message via a hub.
我已经尝试了依赖注入(Autofac),但是无法获得对MessageHub的引用.
I've tried dependency injection (Autofac) however I am unable to get a reference to the MessageHub.
[HubName("messages")]
public class MessageHub : Hub
{
public void ShowNewMessage(string message)
{
Clients.All.showMessageOnPage(message);
}
}
在这里可以看到我的注入尝试:将SignalR IHubContext注入Autofac的服务层
My attempt at Injecting can be seen here: Inject SignalR IHubContext into service layer with Autofac
推荐答案
请查看此选项:
- 在服务(或更好的域)层项目中定义通用集线器接口.类似于
IMessageBroker
. - 在表示层(WebAPI)项目内部实现此接口,并使用
IConnectionManager
进行HubContext检索. - 在表示层的IoC容器(Autofac)中注册接口
- 将界面插入App Service内部
- Define generic hub interface in your Service (or better Domain) Layer project. Something like
IMessageBroker
. - Inside your Presentation Layer (WebAPI) project implement this interface and use
IConnectionManager
for HubContext retrieving. - Register the interface in an IoC Container (Autofac) in the Presentation Layer
- Inject the interface inside App Service
伪代码:
域层:
public interface IMessageBroker
{
void ShowNewMessage(string message)
}
服务层:
public class NotificationService: INotificationService
{
private readonly IMessageBroker _messageBroker;
public NotificationService(IMessageBroker messageBroker)
{
_messageBroker = messageBroker;
}
public void RunNotification(string message)
{
_messageBroker.ShowNewMessage(message);
}
}
演示层:
[HubName("messages")]
public class MessageHub: Hub
{
public void ShowNewMessage(string message)
{
Clients.All.showMessageOnPage(message);
}
}
public class MessageBroker: IMessageBroker
{
private readonly IConnectionManager _connectionManager;
public MessageBroker(IConnectionManager connectionManager)
{
_connectionManager = connectionManager;
}
public void ShowNewMessage(string message)
{
var hub = _connectionManager.GetHubContext<MessageHub>();
// Use Hub Context and send message
}
}
Autofac注册(演示层):
// Register Hubs
builder.RegisterHubs(Assembly.GetExecutingAssembly());
// Register Autofac resolver into container to be set into HubConfiguration later
builder.RegisterType<AutofacDependencyResolver>().As<IDependencyResolver>().SingleInstance();
// Register ConnectionManager as IConnectionManager so that you can get hub context via IConnectionManager injected to your service
builder.RegisterType<ConnectionManager>().As<IConnectionManager>().SingleInstance();
// Register interface
builder.RegisterType<MessageBroker>().As<IMessageBroker>();
也可以使用类似的SO主题.
Also similar SO topic is available here.
这篇关于通过SignalR HubContext从位于集线器之外的项目中的方法发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!