【问题标题】:Ninject Dependency Injection for SignalRSignalR 的 Ninject 依赖注入
【发布时间】:2013-02-05 11:31:57
【问题描述】:

在我的NinjectWebCommon.cs 文件中,在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);

        // Web API Injection
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);                     

        // SignalR Injection
        GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);

        return kernel;
    }

我在想应该为我做这件事,但我在 SignalR 注入时不断收到错误

“无法将类型'SignalR.Ninject.NinjectDependencyResolver'隐式转换为'Microsoft.AspNet.SignalR.IDependencyResolver'”

知道问题出在哪里吗?

【问题讨论】:

  • 我不确定两者是否兼容,但您可以在执行分配时尝试将依赖解析器类型转换为 (Microsoft.AspNet.SignalR.IDependencyResolver)
  • 它确实消除了错误,但 ninject 依赖注入不起作用。从我看到的帖子来看,这种类型转换一开始就不应该是必要的......不知道问题是什么
  • 你确定你的NinjectDependencyResolver继承自Microsoft.AspNet.SignalR.IDependencyResolver吗?可以贴一下代码吗?
  • 我对 SignalR 一点也不熟悉,您在演员表的一侧使用“I”接口,而在另一侧使用“真实对象”。是否有“I”NinjectDependencyResolver?
  • @AlexG SignalR.Ninject.NinjectDependencyResolver 由 SignalR.Ninject 库提供,所以我只是使用它。是的,它继承自 DefaultDependencyResolver,而 DefaultDependencyResolver 又继承自 IDependencyResolver

标签: c# asp.net asp.net-mvc ninject signalr


【解决方案1】:

我不确定你是否找到了答案。从 1.0.0 版开始,他们已经改变了 DI 在 SignalR 中的工作方式,并且 SignalR.Ninject 包不起作用 - 我为此写了一篇小博客文章:http://myrandomcodesnippets.wordpress.com/2013/03/29/ninject-dependency-injection-with-signalr-1-0-1/

基本上,您需要创建自己的实现,这与 SignalR.Ninject 实现相同:

GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);

当您创建新类时,它希望从 IDependancyResolver 继承,不要为此烦恼并使用:

public class SignalRNinjectDependencyResolver : DefaultDependencyResolver
{
    private readonly IKernel _kernel;

    public SignalRNinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
    }
}

希望这会有所帮助。

【讨论】:

  • SignalRNinjectDependencyResolver 很好,但不足以在解决方案中使用模块。请更新?
  • 自从我写这篇文章以来,SignalR 已经有了很大的进步。您可能想看看如何使用 Owin 实现 SignalR/发布问题。