public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(kernel); return kernel; } private static void RegisterServices(IKernel kernel) { kernel.Bind<IFoo>().To<Foo>(); }
我们有一个新的要求,我们认为SignalR将能够满足,所以我们在项目中安装了SignalR 2 nuget软件包.我创建了一个Hub,并对如何在项目中实现依赖注入进行了一些搜索,并发现了一篇文章,建议创建一个SignalRDependencyResolver. http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection
该文章在Startup.cs文件中创建一个用于在OWIN中注册SignalR的内核:
public class Startup { public void Configuration(IAppBuilder app) { var kernel = new StandardKernel(); var resolver = new NinjectSignalRDependencyResolver(kernel); kernel.Bind<IStockTicker>() .To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>() // Bind to StockTicker. .InSingletonScope(); // Make it a singleton object. kernel.Bind<IHubConnectionContext>().ToMethod(context => resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients ).WhenInjectedInto<IStockTicker>(); var config = new HubConfiguration() { Resolver = resolver }; app.MapSignalR(config); } }
问题在于,这种方法使我创建了两个不同的内核,他们似乎有自己的依赖关系,他们知道如何解决.如果我有一个在NinjectWebCommon中定义的依赖关系,Hub不知道如何解决依赖关系.不要在NinjectWebCommon中暴露我的内核,使用Ninject.MVC3包将DI添加到SignalR中的正确方法是什么?
解决方法
假设您已经创建了一个NinjectSignalRDependencyResolver类,除了以下代码片段中突出显示的行以外,不需要添加任何其他代码:
private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); // THIS LINE DOES IT!!! Set our Ninject-based SignalRDependencyResolver as the SignalR resolver GlobalHost.DependencyResolver = new NinjectSignalRDependencyResolver(kernel); RegisterServices(kernel); return kernel; }
除了上述之外,除了在NinjectWebCommon的RegisterServices方法中声明绑定外,还需要做更多的事情.在你的例子中,这将是:
private static void RegisterServices(IKernel kernel) { kernel.Bind<IStockTicker>() .To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>() // Bind to StockTicker. .InSingletonScope(); // Make it a singleton object. kernel.Bind<IHubConnectionContext>().ToMethod(context => resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients ).WhenInjectedInto<IStockTicker>(); }
除了您创建的NinjectSignalRDependencyResolver类,不需要添加其他代码.从整体上讲,OwinStartup类保持不变,如下所示:
public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } }
上述例子实现了以下重要结果,这些结果是您在问题中提出的:
>你只有一个Ninject Kernel创建
>内核和所有绑定配置仍然局限于NinjectWebCommon
>默认的SignalR解析器是您的NinjectSignalRDependencyResolver
>实现了对所有SignalR集线器的依赖注入
希望这可以帮助人们.