我有以下简单的Hub类来列出使用注入用户服务的用户.使用NinjectSignalRDependencyResolver的启动类.非常简单的客户端脚本.
[HubName("dashboardHub")] public class DashboardHub : Hub { private readonly IUserService _users; public DashboardHub(IUserService users) { _users = users; } public void Initialize() { var users = _users.ListUsers(); Clients.All.UpdateStatus(users); } }
var kernel = new StandardKernel(); var resolver = new NinjectSignalRDependencyResolver(kernel); var config = new HubConfiguration() { Resolver = resolver, }; app.MapSignalR(config);
public class NinjectSignalRDependencyResolver : DefaultDependencyResolver { private readonly IKernel _kernel; public NinjectSignalRDependencyResolver(IKernel kernel) { _kernel = kernel; } public override object GetService(Type serviceType) { return _kernel.TryGet(serviceType) ?? base.GetService(serviceType); } public override IEnumerable
我在RegisterServices内以标准方式注册Ninject接口
private static void RegisterServices(IKernel kernel) { kernel.Bind().To ().InSingletonScope(); ... }
用脚本打开客户端时.代码运行,没有生成异常或脚本错误.永远不会调用Dashboard的构造函数,也不会调用Initialize()方法 - 即使JavaScript中存在对象,方法也是如此.永远不会将用户列表填充为client.updateStatus永远不会被调用.
如果我向Hub类添加一个默认构造函数,那么调用它也是如此,而Initialize方法也是如此 - 但是当私有IUserService变量为null时,它显然会被忽略.
public DashboardHub() { }
如何配置SignalR 2.0和Ninject以允许集线器具有依赖注入的构造函数参数?
实现这一目标的最简单方法是完全摆脱Custom Dependency解析器,而只使用一个非常简单的IHubActivator.
public void Configuration(IAppBuilder app) { app.MapSignalR(); }
public class HubActivator : IHubActivator { private readonly IKernel container; public HubActivator(IKernel container) { this.container = container; } public IHub Create(HubDescriptor descriptor) { return (IHub)container.GetInstance(descriptor.HubType); } }
private static void RegisterServices(IKernel kernel) { GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new HubActivator(kernel)); kernel.Bind<IUserService >().To<UserService>().InSingletonScope(); ... }
很简单 - 一切正常,接口被注入到构造函数中,正如您所期望的那样......