如何将依赖项注入global.asax.cs

mag*_*tte 36 dependency-injection unity-container asp.net-mvc-3

如何将依赖项注入global.asax.cs,即MvcApplication类?

以前使用服务定位器(反)模式进行依赖注入,我试图通过使用IOC容器(特别是Unity.Mvc3,因为它附带了IDependencyResolver的实现)来遵循我最新的MVC应用程序中的最佳实践建议.框)和构造函数注入.

到目前为止,一切似乎都非常直接,除了一些障碍,其中一个在global.asax.cs中(另一个是自定义属性,但在SO上覆盖了这个问题).

MvcApplication类中的HttpApplication事件处理程序,例如:

Application_Start()
Application_EndRequest(object sender, EventArgs e)
Application_AcquireRequestState(object sender, EventArgs e)
Run Code Online (Sandbox Code Playgroud)

可能需要外部依赖,例如依赖ILogService.那么如何在不借助例如服务定位器(反)模式的情况下注入它们

private static ILogService LogService
{
    get
    {
        return DependencyResolver.Current.GetService<ILogService>();
    }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助/建议非常感谢!

Mar*_*ann 38

global.asax.cs中的类是您的组合根,因此您不能(也不应该)从外部向其中注入任何内容.

但是,MvcApplication类只有一个实例,因此如果您需要在其中一个方法中使用服务,则可以将其声明为成员字段 - 例如:

public class MvcApplication : System.Web.HttpApplication
{
    private readonly ILogService log;

    public MvcApplication()
    {
        this.log = new MyLogService();
    }

    protected void Application_Start()
    {
        // ...

        this.log.Log("Application started");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在Composition Root博客上+1.好东西! (5认同)
  • 我不.Composition Root是Humble Object的一个示例(http://xunitpatterns.com/Humble%20Object.html).如果需要从中调用复杂逻辑,可以委托另一个*可以*进行单元测试的类. (4认同)
  • 嗯,你在博客文章中说"只能从组合根中引用一个DI容器.所有其他模块都不应该引用容器." 只要它在组合根中,那么这不能给我自由调用解决方案,即我的代码是好的吗?让你的例子困扰我的一件事是你对this.log = new MyLogService()的调用.既然我们已经将容器初始化了,那么为什么不使用它呢?如果我们想要将ILogService换成另一个,我们只需要在一个地方即容器中更改它. (3认同)
  • "只有一个MvcApplication类的实例"是完全错误的 - 每个并行处理的请求都有一个HttpApplication实例.请注意,不会在每个新创建的实例上调用Application_Start,而是针对每个正在运行的Web应用程序调用一次.关于此的优秀博客文章:http://blog.andreloker.de/post/2008/05/HttpApplication-instances.aspx (3认同)