Dis*_*ile 14 asp.net-mvc ninject signalr
我有一个使用Ninject依赖注入的现有MVC应用程序.我安装了Ninject.MVC3 nuget包,它在我的App_Start中创建了一个名为NinjectWebCommon的类,它完全隔离了内核并注册了我的所有绑定:
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>();
}
Run Code Online (Sandbox Code Playgroud)
我们有一个新的要求,我们认为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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是这种方法让我创建了两个不同的内核,它们似乎有自己的一组依赖关系,他们知道如何解决.如果我在NinjectWebCommon中定义了依赖项,则Hub不知道如何解决该依赖项.如果没有在NinjectWebCommon中暴露我的内核,使用Ninject.MVC3包将DI添加到SignalR的正确方法是什么?
dca*_*son 30
目前的答案都没有直接回答你的问题.一旦您确切知道该做什么,那么实现您所追求的结果非常简单.执行此操作的"正确" CreateKernel方法是在NinjectWebCommon类的方法中设置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;
}
Run Code Online (Sandbox Code Playgroud)
除了上述之外,除了在RegisterServices方法中声明绑定之外,不需要做任何其他事情NinjectWebCommon.在您的示例中,这将看起来像:
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>();
}
Run Code Online (Sandbox Code Playgroud)
除了NinjectSignalRDependencyResolver您创建的类之外,不需要添加其他代码.重要的是,OwinStartup类保持不变,如下所示:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
Run Code Online (Sandbox Code Playgroud)
以上示例实现了以下重要结果,这些结果是您在问题中提出的:
NinjectSignalRDependencyResolver希望这可以帮助人们.
您是否尝试过将其StockTickerHub本身添加到内核中?
默认情况下,SignalR 用于Activator.CreateInstance构造没有任何构造函数参数的集线器。如果您想将自己的依赖项注入到 Hub 中,可以通过使用 SignalR 的依赖项解析器注册 Hub 来实现。
如果您想真正发挥创意,您可以注册自己的集线器,IHubActivator而不是单独注册所有集线器。
我在这个答案中详细介绍了默认情况下如何创建集线器:SignalR with IoC (Castle Windsor) - which life for hubs?
| 归档时间: |
|
| 查看次数: |
7372 次 |
| 最近记录: |