我正在学习asp.net mvc 3.其中一项新功能是依赖注入。有人能告诉我它是什么吗?为什么有用?什么时候使用它?感谢
答案 0 :(得分:6)
依赖注入是为消费代码提供依赖关系而不是负责实例化对象本身的代码的过程。在一个原始示例中,您可能有一个类负责计算所呈现服务的发票。你实现它并调用它的'Calculate'方法:
public class InvoiceBiller
{
public void Bill()
{
Calculator calculator = new Calculator();
var totalAmountDue = calculator.CalculateBill(hoursWorked);
}
}
此方法取决于Calculator类。没关系,它有效。但是,依赖注入会让你“注入”Calculator依赖:
public class InvoiceBiller
{
private readonly Calculator calculator;
public InvoiceBiller(Calculator calculator)
{
this.calculator = calculator;
}
public void Bill()
{
var totalAmountDue = calculator.CalculateBill(hoursWorked);
}
}
正如您在第二个示例中所看到的,InvoiceBiller类通过其构造函数(一种称为构造函数注入的依赖注入形式)被赋予了一个Calculator对象。 InvoiceBiller不再关心如何获取账单的实例,只需给出一个。
这有助于测试。您可以从测试中传入您想要的任何计算器实例。在实际产品的运行时,您可以传入连接到数据库的计算器并查看每小时费率。为了测试,您传入一个使用硬编码速率的计算器,这样您的测试就不需要访问数据库。
更进一步,你通常传入一个接口而不是一个具体的类型:
public class InvoiceBiller
{
private readonly ICalculator calculator;
public InvoiceBiller(ICalculator calculator)
现在你正在针对接口进行编程而不是实现。再次从您的测试中,您可以使用模拟框架来创建接口类型的模拟并将它们传递给类。
答案 1 :(得分:3)
事实上,这里有两个问题。有“什么是依赖注入?”和“MVC 3中的新增内容'增加了'依赖注入支持?'。”
依赖注入是一种编程模式,当类在使用它们之前没有定义其他类的新对象时(例如需要在DB中记录电子邮件的某些Email Sender类不会创建Logger的新实例),但请求它提供甚至不知道它可能是哪个类(使用接口,在我们的例子中说ILogger)。这里的记录器将是一个依赖项,并且通过多种方式请求/注入此依赖项,要么作为依赖类的构造函数参数(例如EmailSender),要么仅将其作为类“set”访问器的属性,等...
有一些名为Dependency Injection库的库,或者Inversion Of Control Container。这些库是您定义应在运行时使用哪些类以及使用哪些其他特定值的库,并告诉他们为您创建对象(如创建EmailSender实例),递归地传递所有依赖项(所以,如果ILogger实际上是一个需要连接字符串的DBLogger,它也会发送它等等。)。例如Windsor,Ninject,Autofac,Microsoft Unity,......
有关示例代码和更清晰的示例,请参阅以前在ASP.NET MVC团队中工作的人的免费视频:
http://tekpub.com/view/concepts/1
ASP.NET MVC总是允许一个工厂类,您可以在其中覆盖Controller类的创建方式(这样您就可以使用DI容器库来创建控制器及其依赖项,就像它是或者EmailSender类一样)。 ASP.NET MVC 3.0中的内容是对现有功能的改进,并提供了更多类似的方法,以便更容易在整个ASP.NET MVC上进行DI
和
查看详细信息......
答案 2 :(得分:2)
可能更适合程序员,但首先要了解控制反转
http://en.wikipedia.org/wiki/Inversion_of_control
http://www.martinfowler.com/articles/injection.html
这个想法是组件不应该知道如何获取/创建它的依赖项,应该提供它完成工作所需的内容。