我已经阅读了很多关于IOC和Unity的文章,让我感到困惑:(
所以回到基础知识可以告诉我以下代码的作用吗?
private IStudent _student;
public HomeController(IStudent student)
{
_student= student;
}
public interface IStudent
{
// Some method
}
Itz Basic,但我试图从外行的角度来理解。上面的代码到底是做什么的?
答案 0 :(得分:23)
HomeController在Student上有一个依赖,因为它将一些责任委托给Student class。
实施的一种方法是:
public HomeController()
{
private Student _student;
public HomeController()
{
_student = new Student();
}
}
public class Student
{
// Some method
}
但是HomeController对Student class有一个 hard 依赖。如果您想使用Student的其他实现(例如,想要在对HomeController进行单元测试时模拟Student),该怎么办?您将不得不修改Student类或HomeController类(或使用其他一些不太好的选项)。这意味着您的HomeController 紧密耦合到学生班。
另一种方式是您发布的代码:
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实现。只要您使用它注册正确的接口和类,这就是Depedency Injection Container(在您的情况下为Unity)将会处理的事情。
_container.Register<IStudent, Student>();
因此,当需要HomeController的新实例时,容器将识别需要IStudent的实例。因此,它将实例化IStudent的已注册实例,并在实例化HomeController类时将其作为参数传递。
另外,请注意您所指的是“依赖注入”(这是IoC的一种特定形式)。还有其他形式的IoC(例如回调,观察者模式等)。
修改强> 不要忘记阅读DI上的popular article。
答案 1 :(得分:2)
在IoC中,您需要注册接口和实现接口的类。 因此,一旦您注册,那么每当您拥有上述签名时,IoC将自动创建一个IStudent实现类的实例,并在初始化控制器时将其注入对象。 它节省了宣布成员的时间和精力。在上面的例子中,你只需要一个声明,但它可能更多的数字和那些可能需要更多的实例传递给控制器。 一旦我们正确地注册了这些,IoC就会完成它的工作。事实上,我们可以决定注入成员的范围/生命周期。它可以是PerInstance / Per Request / Or Singleton。
有多种IoC框架可供您使用,您可以使用哪种框架。
答案 2 :(得分:2)
一般来说,它被称为注入类的依赖关系,考虑一个类或者确切地说是一个处理所有东西的GOD类(验证用户输入,与数据库协调,生成HTML输出等)所以你保留所有您的代码在一个地方,或者您可以说您使用单个类开发所有软件,是不是很好?
答案取决于你组织事物的方式,你认为,组织它所属的事物是有益的,而不是你将在上面的GOD课程中看到问题。
因此,就OOPS而言,单个类shd有一个原因需要改变,但需要完成工作,而不是从服务中获取帮助。
你的HomeController正在做同样的事情,因为它不想过度劳累,它已经要求Student对象处理学生。
答案 3 :(得分:1)
当IOC解析器构造一个新的HomeController对象时,它将采用一个对象来实现IOC容器(您注册的)通过其构造函数提供的IStudent接口。
您可以阅读有关Constructor Injection here.
的更多信息