HomeController依赖于 Student,因为它将一些责任委托给 Student 类。
一种实现方式是:
public HomeController()
{
private Student _student;
public HomeController()
{
_student = new Student();
}
}
public class Student
{
// Some method
}
但是 HomeController 对 Student 类有很强的依赖性。如果您想使用 Student 的其他一些实现(例如,想在对 HomeController 进行单元测试时模拟 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 的任何实现,即在您的单元测试中您可以传递 IStudent 的模拟对象,在您的实际代码中您将传递 Student 类的对象。所以你的 HomeController 现在依赖于 IStudent 接口(抽象)而不是 Student 类(一个实现)。这符合 OOP 原则:
编程接口,而不是实现。
依赖于抽象。不要依赖具体的类。
此外,它现在具有软依赖性。它不再与 Student 类紧密耦合。它是松耦合的。现在,通常您不必担心在实例化 HomeController 时应该通过哪个 IStudent 实现。只要您使用它注册正确的接口和类,这就是依赖注入容器(在您的情况下为 Unity)将负责的事情。
_container.Register<IStudent, Student>();
因此,当需要 HomeController 的新实例时,容器将识别出需要 IStudent 的实例。所以它将实例化 IStudent 的注册实例,并在实例化 HomeController 类时将其作为参数传递。
另外,请注意,您所指的是“依赖注入”(这是 IoC 的一种特定形式)。还有其他形式的 IoC(例如回调、观察者模式等)。
编辑:
不要忘记阅读关于 DI的热门文章。