如何在 ASP.NET 5 (vNext) 中设置 SignalR Hub 依赖注入?
How can I set up SignalR Hub Dependency Injection in ASP.NET 5 (vNext)?
尝试使用属于 ASP.NET 5 的 SignalR-Server 对我的 SignalR Hub class 进行依赖注入(repo). I tried to figure this out from the tutorial at this link 但我似乎无法确定我是如何鉴于 GlobalHost
不再可用,可以执行此操作。这是我正在尝试做的事情:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddSingleton<IState, State>();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR();
}
MyHub.cs
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)
构造函数注入所需的依赖项?
好的。现在,我使用了 Autofac,我不确定它是否具有 ASP.NET 5 集成。但是,如果(目前)只针对 .NET 4.6,你应该没问题。
我刚刚发布了 this repository,其中包含一个使用 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
中阅读了一些关于依赖注入的内容后,它似乎是以统一的方式完成的。 If you haven't had a look at this article, I recommend it, even though it doesn't specifically show SignalR
DI.
我通过在 Startup.ConfigureServices
中添加我的 State
class 作为 IState
的单身人士,然后制作 ServiceProvider
属性 在我的 Startup.cs class 上公开可用。从那里,我能够 GetRequiredService
在我的 SignalR Hub class 的构造函数中。这不是理想的解决方案,希望我能够调整它以在平台达到 RC 时使用 constructor/property 注入。
这是我的代码:
Startup.cs
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
中的对象,让我能够将我的应用程序状态持久保存在内存中。
最好的方法(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);
}
}
然后启动 class
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IState, State>();
//... other services
GlobalHost.DependencyResolver = new CustomSignalRDependencyResolver(services.BuildServiceProvider());
}
我只是制作了带有依赖关系的构造函数。例如,我需要在集线器中使用我的 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);
}
}
你非常接近。您只需要:
public class MyHub : Hub
{
readonly IState _state;
public MyHub(IState state)
{
_state = state;
}
}
在 .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();
}
}
尝试使用属于 ASP.NET 5 的 SignalR-Server 对我的 SignalR Hub class 进行依赖注入(repo). I tried to figure this out from the tutorial at this link 但我似乎无法确定我是如何鉴于 GlobalHost
不再可用,可以执行此操作。这是我正在尝试做的事情:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddSingleton<IState, State>();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR();
}
MyHub.cs
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)
构造函数注入所需的依赖项?
好的。现在,我使用了 Autofac,我不确定它是否具有 ASP.NET 5 集成。但是,如果(目前)只针对 .NET 4.6,你应该没问题。
我刚刚发布了 this repository,其中包含一个使用 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
中阅读了一些关于依赖注入的内容后,它似乎是以统一的方式完成的。 If you haven't had a look at this article, I recommend it, even though it doesn't specifically show SignalR
DI.
我通过在 Startup.ConfigureServices
中添加我的 State
class 作为 IState
的单身人士,然后制作 ServiceProvider
属性 在我的 Startup.cs class 上公开可用。从那里,我能够 GetRequiredService
在我的 SignalR Hub class 的构造函数中。这不是理想的解决方案,希望我能够调整它以在平台达到 RC 时使用 constructor/property 注入。
这是我的代码:
Startup.cs
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
中的对象,让我能够将我的应用程序状态持久保存在内存中。
最好的方法(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);
}
}
然后启动 class
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IState, State>();
//... other services
GlobalHost.DependencyResolver = new CustomSignalRDependencyResolver(services.BuildServiceProvider());
}
我只是制作了带有依赖关系的构造函数。例如,我需要在集线器中使用我的 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);
}
}
你非常接近。您只需要:
public class MyHub : Hub
{
readonly IState _state;
public MyHub(IState state)
{
_state = state;
}
}
在 .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();
}
}