全局访问Ninject内核

Fre*_*eau 16 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我有一些类,例如,没有与控制器接口的外观类,我想开始一个依赖链,我的理解是我应该使用:

_className = kernel.Get<IClassName>();
Run Code Online (Sandbox Code Playgroud)

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

那么,是否有可能从我的应用程序中的任何位置访问在Application Start中在Global.asax中实例化的现有内核,或者是否有更好的方法来完成此操作?

问候,

弗雷德城堡

小智 26

最简单的方法(IMO):

_className = (IClassName)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IClassName));
Run Code Online (Sandbox Code Playgroud)


det*_*ale 7

如果与System.Web.MVC一起使用,则新版本的Ninject具有此方法:

__CODE__

除非您需要动态操作DI绑定,但实例化StandardKernel有点重.

__CODE__


小智 0

听起来您需要更多 Ninject 的工厂模式实现。您可以将内核从 Global.asax 迁移到可以与应用程序的其余部分进行交互的工厂类。

或者,如果您遇到在运行时指定的参数是为了确定接口绑定的情况,您可以包装服务。这是 DI 和 ServiceLocater 的混合设置,但 ServiceLocater 仅发生在服务级别实例化时,所有其他层通常以 DI/IOC 模式进行编码。

MyService : IService1
{
    public void DoSomething(MyCustomParameter parameter)
    {
        //Builds the Kernel using the supplied parameter
        //We've in our resolver bound IService1 To MyActualService
        var trueService = kernel.Get<IService1>();
        return trueService.DoSomething(parameter);
    }
}

MyActualService : IService1
{
    public void DoSomething()
    {
        //Do the Actual work
    }
}
Run Code Online (Sandbox Code Playgroud)