[英]How can I set up SignalR Hub Dependency Injection in ASP.NET 5 (vNext)?
尝试使用作为 ASP.NET 5 ( repo ) 一部分的 SignalR-Server 对我的 SignalR Hub 类进行依赖注入。 我试图从本链接的教程中弄清楚这一点,但鉴于GlobalHost
不再可用,我似乎无法确定如何做到这一点。 这是我想要做的:
启动文件
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddSingleton<IState, State>();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR();
}
我的中心
public class MyHub : Hub
{
public IState State { get; set; }
// SignalR accepts this parameterless ctor
public MyHub()
{
}
// SignalR won't use this because it has a parameter
public MyHub(IState state)
{
State = state;
}
}
如何让SignalR-Server使用MyHub(IState state)
构造函数注入所需的依赖项?
最好的方法(对于Asp.Net 5)为接收IServiceProvider的DefaultDependencyResolver创建一个自定义解析器:
public class CustomSignalRDependencyResolver : DefaultDependencyResolver
{
private readonly IServiceProvider _serviceProvider;
public CustomSignalRDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override object GetService(Type serviceType)
{
var service = _serviceProvider.GetService(serviceType);
return service ?? base.GetService(serviceType);
}
}
然后在启动类上
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IState, State>();
//... other services
GlobalHost.DependencyResolver = new CustomSignalRDependencyResolver(services.BuildServiceProvider());
}
你很亲密 您只需:
public class MyHub : Hub
{
readonly IState _state;
public MyHub(IState state)
{
_state = state;
}
}
好。 现在,我使用了Autofac ,但我不确定它是否已集成ASP.NET 5。 但是,如果(目前)仅针对.NET 4.6,则应该没问题。
我刚刚发布了此存储库 ,其中包含使用SignalR和Autofac进行依赖项注入的基本项目设置。
现在,我进行了依赖项注入设置,以实现以下目的:
能够将依赖项注入我的中心
能够获取我的集线器的上下文以便在不使用GlobalHost
情况下从集线器外部发送给客户端(它在.NET 5中不再可用,但也不应使用,因为它是静态的全局对象)
我希望您能够成功设置项目(即使我认为您不能将DNX
保留在构建选项中,因为Autofac
尚未准备好.NET 5库。
我希望这有帮助! 祝你好运!
https://github.com/radu-matei/SignalRDependencyInjection
编辑:如果您想使用NInject(并且如果要定位DNX
,则可以构建自己的依赖项解析器,则可以从SignalR的官方人员(实际上是从编写SignalR的人员那里)遵循此存储库:
https://github.com/DamianEdwards/NDCLondon2013/tree/master/DependencyInjection
在此演示中,他们使用NInject创建了自己的依赖关系解析器,因此,如果您有NInject库,则对DNX
定位不会有任何问题。
更新:在阅读了有关ASP.NET 5
依赖注入的一些知识之后,看来它是以统一的方式完成的。 如果您没有看过这篇文章,即使它没有专门显示SignalR
DI,我也推荐它。
通过在Startup.ConfigureServices
IState
State
类添加为IState
的Singleton,然后在Startup.cs类上公开提供ServiceProvider
属性,我设法解决了这一问题。 从那里,我能够GetRequiredService
我SignalR集线器类的构造函数中。 这不是理想的解决方案,希望当平台达到RC时,我将能够对其进行调整以使用构造函数/属性注入。
这是我的代码:
启动文件
public static IServiceProvider __serviceProvider;
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddSingleton<IState, State>();
__serviceProvider = services.BuildServiceProvider();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR();
}
MyHub.cs
public class MyHub : Hub
{
public IState State { get; set; }
public MyHub()
{
State = (IState) Startup.__serviceProvider.GetRequiredService(typeof (IState));
}
public override Task OnConnected()
{
State.Clients = Clients;
State.Groups = Groups;
return base.OnConnected();
}
}
通过这种方式,我能够设置属性和调用方法IState
从内部实施对象MyHub
,让我坚持在内存中我的应用程序的状态。
我只是简单地使构造函数具有依赖关系。 例如,我需要中心中的IUnitOfWork
实例(在启动时配置)。 那是工作代码
[HubName("receipts")]
public class ReceiptsHub : Hub
{
public IUnitOfWork<string> UnitOfWork { get; set; }
public ReceiptsHub(IUnitOfWork<string> unitOfWork) : base()
{
UnitOfWork = unitOfWork;
}
public override Task OnConnected()
{
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
return base.OnDisconnected(stopCalled);
}
}
在 .NET 5 中,您可以直接解析IServiceProvider
,然后您可以获得所需的服务。 请检查以下代码:
public class MyHub : Hub
{
public IState State { get; set; }
private readonly IServiceProvider _serviceProvider;
public MyHub(IServiceProvider serviceProvider)
{
_serviceProvider=serviceProvider;
State = _serviceProvider.GetRequiredService<IState>();
}
public override Task OnConnected()
{
State.Clients = Clients;
State.Groups = Groups;
return base.OnConnected();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.