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

时间:2013-03-11 06:03:32

标签: c# asp.net-mvc constructor

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

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

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

public interface IStudent 
{
     // Some method
}

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

4 个答案:

答案 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.

的更多信息