在Application_Start中访问ninject内核

tel*_*all 16 ninject asp.net-mvc-3

我正在使用Ninject和与nuget一起安装的MVC3扩展.我的内核设置代码位于App_Start/NinjectMVC3.cs文件中.一切都在控制器中运行良好,但我无法弄清楚如何(正确)绑定Global.asax.cs MvcApplication代码中的接口.

我最终使用了一个hack(创建一个返回bootstrap.kernel的公共NinjectMVC3.GetKernel()方法).但是,这将被弃用,必须有一个正确的方法来做到这一点,我没有看到.

这是我的代码:

public class LogFilterAttribute : ActionFilterAttribute
{
    private IReportingService ReportingService { get; set; }
    public LogFilterAttribute( IReportingService reportingService )
    {
        this.ReportingService  = reportingService;
    }
    ...
}

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters( GlobalFilterCollection filters )
    {
        filters.Add( new HandleErrorAttribute() );
        filters.Add( new LogFilterAttribute()  );
    }
    ...
    protected void Application_Start()
    {
        ...
        RegisterGlobalFilters( GlobalFilters.Filters );
        // NOTE hack:
        var kernel = NinjectMVC3.GetKernel();
        var logger = kernel.Get<ILogger>();
        var bw = new BackgroundWork(logger);
        Application["BackgroundWork"] = bw;
        bw.Start();
    }
}
Run Code Online (Sandbox Code Playgroud)

我感兴趣的有两个接口.第一个是将对象绑定到Global变量(BackgroundWork的ILogger).

第二个是ActionFilter.我阅读了http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/,但我看不出它是如何插入实际注册的(过滤器) .加).

如果可以避免,我不想使用Property Inject.

有关正确方法的任何想法吗?谢谢

Aar*_*ght 24

MVC 3引入了DependencyResolver填充单例的内容,Ninject扩展支持它.MvcApplication如果需要,可以在课堂上使用它:

protected void Application_Start()
{
    // ...
    var logger = DependencyResolver.Current.GetService<ILogger>();
}
Run Code Online (Sandbox Code Playgroud)

现在我应该指出,没有必要使用动作过滤器来执行此操作.在Ninject.MVC3中你应该使用BindFilter语法,如下所示:

// Declare empty attribute
public class MyFilterAttribute : FilterAttribute { }

// Dependency module
public class MyModule : NinjectModule
{
    public override void Load()
    {
        // Other bindings
        // ...
        this.BindFilter<MyActionFilter>(FilterScope.Action, 1)
            .WhenControllerHas<MyFilterAttribute>();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须使用this因为BindFilter是扩展方法,并且还必须引用Ninject.Web.Mvc.FilterBindingSyntax命名空间.

  • @user:是的,`DependencyResolver`只是一个不那么巧妙伪装的服务定位器,但在这种情况下你没有任何其他选择,因为Ninject没有*创建你的MvcApplication因此不能做任何依赖注射它.应用程序本身是一个Singleton对象,因此使用单例服务定位器确实没有不一致.如果您在*Controllers*中引用了"DependencyResolver.Current",我会担心,但是在"MvcApplication"类中...... meh,并不重要. (3认同)