Controller中带参数的构造函数 – MVC

我读过很多关于IOC和Unity的文章,让我感到困惑:(

所以回到基础可以告诉我以下代码的作用吗?

private IStudent _student; public HomeController(IStudent student) { _student= student; } public interface IStudent { // Some method } 

Itz Basic,但我试图从外行的角度来理解。 上面的代码到底是做什么的?

HomeController 依赖于Student,因为它将一些责任委托给Student类。

一种实施方式是:

 public HomeController() { private Student _student; public HomeController() { _student = new Student(); } } public class Student { // Some method } 

但是HomeController对Student class有很强的依赖性。 如果您想使用Student的其他实现(例如,想要在对HomeController进行unit testing时模拟Student),该怎么办? 您将不得不修改Student类或HomeController类(或使用其他一些不那么好的选项)。 这意味着您的HomeController Student类紧密耦合

另一种方式是您发布的代码:

 public class HomeController { private IStudent _student; public HomeController(IStudent student) { _student = student; } } public interface IStudent { // Some method } public class Student : IStudent { // Implementation of some method } 

在这里,您可以传递IStudent的任何实现,即在您的unit testing中,您可以传递IStudent的模拟对象,在您的实际代码中,您将传递Student类的对象。 所以你HomeController现在依赖于IStudent接口(抽象)而不是Student类(一个实现)。 这符合OOP原则:

程序到接口,而不是实现。

取决于抽象。 不要依赖具体的课程。

此外,它现在具有软依赖性。 它不再与Student课程紧密耦合。 它松散耦合 。 现在,通常您不必担心在实例化HomeController时应该通过哪个IStudent实现。 只要您使用它注册正确的接口和类,这就是Depedency Injection Container(在您的情况下为Unity)将要处理的事情。

 _container.Register(); 

因此,当需要HomeController的新实例时,容器将识别需要IStudent的实例。 因此,它将实例化IStudent的已注册实例,并在实例化HomeController类时将其作为参数传递。

另请注意,您所指的是“dependency injection”(这是IoC的一种特定forms)。 还有其他forms的IoC(例如回调,观察者模式等)。

编辑:别忘了阅读关于DI的热门文章 。

一般来说,它被称为注入类的依赖关系,考虑一个类或者确切地说是一个处理所有东西的GOD类(validation用户输入,与数据库协调,生成HTML输出等),所以你要保留所有代码单个地方或者你可以说你使用单一类开发所有软件,是不是很好?

答案取决于你组织事物的方式,你认为,组织它所属的事物是有益的,而不是你将在上面的GOD课程中看到问题。

因此,就OOPS而言,单个类shd有一个原因需要改变,但需要完成工作,而不是从服务中获取帮助。

而你的HomeController也在做同样的事情,因为它不想过度劳累,它要求Student对象处理学生。

在IoC中,您需要注册接口和实现接口的类。 因此,一旦您注册,那么只要您有上述签名,IoC就会自动创建一个IStudent实现类的实例,并在初始化控制器时将其注入对象。 它节省了宣布成员的时间和精力。 在上面的例子中,你只需要一个声明,但它可能更多的数字和那些可能需要更多的实例传递给控制器​​。 一旦我们正确地注册了这些,IoC就会完成它的工作。 事实上,我们可以决定注入成员的范围/生命周期。 它可以是PerInstance / Per Request / Or Singleton。

有几个IoC框架可供您使用,您可以使用哪个框架。

当一个新的HomeController对象由IOC解析器构造时,它将采用一个对象来实现IOC容器(您注册的)通过其构造函数提供的IStudent接口。

您可以在此处阅读有关构造函数注入的更多信息。