微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc – SignalR 2依赖注入与Ninject

我有一个现有的MVC应用程序正在使用依赖注入与Ninject.我安装了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>();
}

我们有一个新的要求,我们认为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中的正确方法是什么?

解决方法

目前的答案都不直接回答您的问题.一旦你知道要做什么,还要实现你所追求的结果是非常简单的.要做到这一点的“正确”方法是将SignalR的依赖关系解析器设置在NinjectWebCommon类的CreateKernel方法中.

假设您已经创建了一个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集线器的依赖注入

希望这可以帮助人们.

原文地址:https://www.jb51.cc/aspnet/249020.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐