【问题标题】:What is the proper way to inject my own custom dependencies on an ASP.NET MVC controller?在 ASP.NET MVC 控制器上注入我自己的自定义依赖项的正确方法是什么?
【发布时间】:2012-09-12 14:54:21
【问题描述】:

我有一个架构,其中所有默认依赖项都通过InitializeOnActionExecuting 自动注入。这一切都像一个魅力,因为在运行时(不是测试),默认的控制器激活器将调用这些方法并传入正确的具体对象。很好。

当我有一个无法在 InitializeOnActionExecuting 方法中注入的自定义依赖项时,我的问题就开始了。

示例:

public class MyController
{
    private IEmailSender emailSender = null;
}

嗯.. 在运行时emailSender 将为空,除非我将其设置为其他值。在这种情况下,我会得到一些不太好的东西,像这样:

public class MyController
{
    private IEmailSender emailSender = null;
    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
         if(this.emailSender == null)
              this.emailSender = new SomeConcreteEmailSender();
    }
}

丑陋。我不想做这种“如果为空,则实例化”的事情。

注入IEmailSender 的更复杂的方法是创建我自己的ControllerActivator,它只会在运行时(而不是测试)中调用,并且会自动注入IEmailSender 而无需“如果”执行此操作。但我不想为每个需要注入的控制器创建自定义ControllerActivator

话虽如此,对于 ASP.NET 控制器的自定义依赖注入,什么被认为是标准的?

【问题讨论】:

  • “在自定义方面什么被认为是标准的”——也许你可以看看使用标准的依赖注入框架?

标签: .net asp.net-mvc dependency-injection


【解决方案1】:

话虽如此,在定制方面什么被认为是标准的 ASP.NET 控制器的依赖注入?

构造函数注入:

public class MyController: Controller
{
    private readonly IEmailSender _emailSender;

    public MyController(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    ... actions using the _emailSender here ...
}

对于不希望使用现有依赖注入框架的人(例如,因为他们在一些技术文盲的白痴决定应该使用哪些框架,哪些不应该使用)或者懒得编写自定义依赖解析器的公司:

public class MyController: Controller
{
    private readonly IEmailSender _emailSender;

    public MyController(): this(new SomeConcreteEmailSender())
    {
    }

    public MyController(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    ... actions using the _emailSender here ...
}

【讨论】:

  • 默认的 ControllerActivator 不会调用我的自定义构造函数,这不会让我处理我想要的“如果”
  • 这就是为什么你可以写一个自定义的。或者,如果您不想重新发明轮子,您可以使用现有的依赖注入框架。例如,Ninject 非常漂亮。您所要做的就是安装Ninject.MVC3 NuGet 包,然后在为您创建的AppStart 文件夹中注册您的依赖项。 Ninject 将为您注册一个自定义的dependency resolver,以便您可以在应用程序的许多地方(例如控制器)注入依赖项。
  • 是的,很不错。但选择真的是你的。现有的依赖注入框架太多了。只需选择一个并开始使用它。但就您对控制器的依赖项的设计而言,毫无疑问-> 构造函数注入。它允许对应用程序的不同层进行更弱的耦合和更轻松的单元测试。
  • @AndréPena:你可以使用 Ninject、StructureMap、Autofac、Castle Windsor、Simple Injector,随便选一个。
猜你喜欢
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
相关资源
最近更新 更多