7

我读过几篇关于 IOC 和 Unity 的文章,让我自己感到困惑 :(

所以回到基础,有人能告诉我下面的代码是做什么的吗?

private IStudent _student;
public HomeController(IStudent student)
{
     _student= student;
}

public interface IStudent 
{
     // Some method
}

Itz Basic 但我试图从外行的角度理解。上面的代码究竟做了什么?

4

4 回答 4

23

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的热门文章。

于 2013-03-11T06:42:47.193 回答
2

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

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

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

你的 HomeController 也在做同样的事情,因为它不想过度工作,它已经要求 Student 对象来处理 student。

于 2013-03-11T06:11:09.803 回答
2

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

有许多可用的 IoC 框架,由您决定使用哪一个。

于 2013-03-11T06:10:23.750 回答
1

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

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

于 2013-03-11T06:15:37.683 回答