asp.net-mvc - 全局访问 Ninject 内核

标签 asp.net-mvc ninject

这个问题与 Ninject 没有特别的关系。这更像是一个一般性的编码问题,但我将其发布在这里,以防万一在 Ninject 中可能有更好的方法来处理这个问题,而不是我正在尝试做的事情。

我想知道是否可以从 Global.asax 中的实例全局访问 Ninject 标准内核。

这是代码:

public class MvcApplication : NinjectHttpApplication
{
    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();

        // MVC global registration, routing and filtering code goes here...
    }

    protected override IKernel CreateKernel()
    {
        return Container;
    }

    private static IKernel Container
    {
        get
        {
            IKernel kernel = new StandardKernel();
            kernel.Load(new ServiceModule(), new RepositoryModule());
            return kernel;
        }
    }
}

如果我有一些类,例如不与 Controller 接口(interface)的外观类,我想在其中开始依赖链,我的理解是我应该使用:
_className = kernel.Get<IClassName>();

但是,我知道的唯一方法是创建 Ninject 标准内核的新实例,但如果我理解正确,创建 Ninject 内核的新实例并不是一个好主意,因为这基本上是创建第二个内核。

那么,是否可以从我的应用程序中的任何位置访问在应用程序启动时在 Global.asax 中实例化的现有内核,还是有更好的方法完全做到这一点?

问候,

弗雷德城堡

最佳答案

我设法让服务定位器工作,它似乎工作得很好。当请求通过 MVC Controller 操作方法进入应用程序时,Ninject 以 Ninject.Mvc.Extensions 提供的正常方式运行。它通过 Controller 构造函数注入(inject)实例类。当请求以任何其他方式进入应用程序时,我调用服务定位器以提供该类构造函数中的实例类。

这是代码:

首先,对 Microsoft.Practices.ServiceLocation 的引用

以及下面的 Ninject 适配器类。

public class NinjectServiceLocator : ServiceLocatorImplBase
{
    public IKernel Kernel { get; private set; }

    public NinjectServiceLocator(IKernel kernel)
    {
        Kernel = kernel;
    }

    protected override object DoGetInstance(Type serviceType, string key)
    {
        return Kernel.Get(serviceType, key);
    }

    protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
    {
        return Kernel.GetAll(serviceType);
    }
}

在 Global.asax
public class MvcApplication : NinjectHttpApplication
{
    private static IKernel _kernel;


    protected override IKernel CreateKernel()
    {
        return Container;
    }

    private static IKernel Container
    {
        get
        {
            if (_kernel == null)
            {
                _kernel = new StandardKernel();
                _kernel.Load(new ServiceModule(), new RepositoryModule());

                ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(_kernel));
            }

            return _kernel;
        }
    }
}

请注意,此代码需要使用 Ninject.Mvc.Extensions,它提供依赖解析器回退到默认 Controller 。否则,可能需要自定义依赖解析器。

这似乎解决了我所有的担忧。它创建实例类,解析整个对象图,并在我需要它工作的任何地方工作。而且,据我所知,每个应用程序只有一个 Ninject 标准内核。

我知道使用服务定位器模式不受欢迎,但我想使用多个 Ninject 内核会不受欢迎,甚至更糟。

弗雷德城堡

关于asp.net-mvc - 全局访问 Ninject 内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15338162/

相关文章:

asp.net-mvc - BeginFormSitefinity 表单提交后消失

c# - Ninject 传递实现接口(interface)的类的构造函数参数 typeof

c# - Ninject Providers -> 在提供者中获取另一个依赖项

c# - Ninject 注入(inject)接口(interface)的多重绑定(bind)

c# - 在 Ninject 中是否允许将 IKernel 注入(inject)到一些地方?

asp.net-mvc - 什么时候使用 Html.RenderAction() 合适?

c# - 无法获取属性值 'unobtrusive' : object is null or undefined

c# - Web Api - Controller 外部请求参数

asp.net - MiniProfiler.Stop() 上的 MVC Mini Profiler 异常

c# - 持久 Entity Framework 查询缓存