关于asp.net mvc:什么是依赖注入?

what is Dependency Injection?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is dependency injection?

我正在学习ASP.NET MVC 3。其中一个新特性是依赖注入。有人能告诉我是什么吗?为什么它有用?什么时候用?谢谢


依赖项注入是向使用代码提供依赖项的过程,而不是负责实例化对象本身的代码。在一个原始示例中,您可能有一个类负责计算所提供服务的发票。您将其实例化并调用其"calculate"方法:

1
2
3
4
5
6
7
8
public class InvoiceBiller
{
    public void Bill()
    {
        Calculator calculator = new Calculator();
        var totalAmountDue = calculator.CalculateBill(hoursWorked);
    }
}

这个方法依赖于计算器类。很好,它起作用了。然而,依赖注入会让您"注入"计算器依赖项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class InvoiceBiller
{
    private readonly Calculator calculator;

    public InvoiceBiller(Calculator calculator)
    {
        this.calculator = calculator;
    }

    public void Bill()
    {
        var totalAmountDue = calculator.CalculateBill(hoursWorked);
    }
}

正如您在第二个示例中看到的,invoicefiller类通过其构造函数(一种称为构造函数注入的依赖注入形式)获得了一个计算器对象。Invocifier不再关心如何获取Biller的实例,它只是给出了一个实例。

这有助于测试。您可以从您的测试中传入您想要的任何计算器实例。在实际产品的运行时,您可以通过一个连接到数据库的计算器来查找小时工资。为了测试,您需要传递一个使用硬编码速率的计算器,这样您的测试就不需要访问数据库。

更进一步,您通常会传入一个接口,而不是具体的类型:

1
2
3
4
5
public class InvoiceBiller
{
    private readonly ICalculator calculator;

    public InvoiceBiller(ICalculator calculator)

现在您是针对接口而不是实现进行编程的。同样,从测试中,您可以使用模拟框架来创建接口类型的模拟,并将它们传递给类。


实际上,这里有两个问题。这里有"什么是依赖注入?"以及"MVC 3中新增了什么"增加了更多"依赖注入支持?".

依赖注入是一种编程模式,当类在使用它们之前不定义其他类的新对象时(比如一些需要在DB中记录电子邮件的电子邮件发送者类不会创建记录器的新实例),但是请求在不知道可能是哪个类的情况下提供它(在我们的例子中,使用接口,比如ilogger)。这里的记录器是一个依赖项,通过多种方式请求/注入这个依赖项,或者作为依赖类的构造函数参数请求(例如emailsender),或者只是将其作为类"set"访问器的属性,等等…

有一些库称为依赖注入库,或者控制容器的反转。这些库定义了哪些类应该在运行时真正使用,哪些其他特定的值应该使用,并告诉它们为您创建对象(如创建emailsender实例),递归地将所有依赖项传递给它们(因此,如果ilogger实际上是一个需要连接字符串的dblogger,它也会发送它,等等)..)例如温莎、尼尼特、自动空调、微软联合……

有关示例代码和更清晰的示例,请参见这段来自一个曾在ASP.NET MVC团队工作过的人的免费视频:http://tekpub.com/view/concepts/1

ASP.NET MVC始终允许一个工厂类,您可以在其中重写如何创建控制器类(以便您可以使用DI容器库创建控制器及其依赖项,就像它是或emailsender类一样)。ASP.NET MVC 3.0所带来的是对现有功能的改进,并提供了更多类似于它的方法,这样可以更容易地在整个ASP.NET MVC上执行DI。

  • 官方的ASP.NET MVC 3.0发行说明:附加的依赖项注入支持
  • http://blogs.microsoft.co.il/blogs/gilf/archive/2010/10/17/dependency-injection-in-mvc-3-was-made-easy.aspx
  • http://johan.driessen.se/archive/2010/10/30/dependency-injection-in-asp.net-mvc-3-got-a-lot-simper.aspx

  • ASP.NET MVC 3服务位置:简介(第1部分)
  • ASP.NET MVC 3服务位置:控制器(第2部分)
  • ASP.NET MVC 3服务位置:视图(第3部分)
  • ASP.NET MVC 3服务位置:筛选器(第4部分)

查看他们的详细信息…


可能更适合程序员,但首先要了解控制反转

http://en.wikipedia.org/wiki/inversionu控制

http://www.martinfowler.com/articles/injection.html

其思想是,一个组件不应该知道如何获取/创建它的依赖项,应该提供它完成工作所需要的东西。