C# 控制器中带有参数的构造函数 - MVC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15332159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:26:50  来源:igfitidea点击:

Constructor with parameter in Controller - MVC

c#asp.net-mvcconstructor

提问by user2067567

I have read few articles on IOC and Unity and got my self confused :(

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

So going back to basics can some one tel me what the below code does?

那么回到基础知识,有人可以告诉我下面的代码是做什么的吗?

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

public interface IStudent 
{
     // Some method
}

Itz Basic but am trying to understand from a layman view. What exactly the above code does?

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

采纳答案by publicgk

HomeController has a dependencyon Student because it delegates some responsibility to Student class.

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

One way to implement is:

一种实现方式是:

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

but then HomeController has a harddependency on Student class. What if you wanted to use some other implementation of Student (e.g. wanted to mock Student while unit testing your HomeController). You will have to modify the Student class or HomeController class (or use some other not-so-good option). This means your HomeController is tightly-coupledto Student class.

但是 HomeController严重依赖 Student 类。如果您想使用 Student 的其他一些实现(例如,想在对 HomeController 进行单元测试时模拟 Student)怎么办?您将不得不修改 Student 类或 HomeController 类(或使用其他一些不太好的选项)。这意味着您的 HomeControllerStudent 类紧密耦合

The other way is the code you have posted:

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

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
}

Here, you can pass on any implementation of IStudent i.e. in your unit tests you can pass the mock object of IStudent, in your actual code you will pass object of Student class. So you HomeController is now dependenton the IStudent interface (abstraction) rather than on the Student class (an implementation). This is inline with the OOP principles:

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

Program to interfaces, not implementations.

Depend on abstractions. Do not depend on concrete classes.

编程接口,而不是实现。

依赖于抽象。不要依赖具体的类。

Also, it now has a soft dependency. It's no longer tightly-coupled to the Student class. It's loosely-coupled. Now, generally you don't need to worry about which implementation of IStudent you should pass while instantiating your HomeController. That's something the Depedency Injection Container (Unity in your case) will take care of, as long as you register correct interface and classes with it.

此外,它现在有一个软依赖。它不再与 Student 类紧密耦合。它是松耦合的。现在,通常您无需担心在实例化 HomeController 时应该通过 IStudent 的哪个实现。只要您使用它注册正确的接口和类,这就是依赖注入容器(在您的情况下为 Unity)会处理的事情。

_container.Register<IStudent, Student>();

So when a new instance of HomeController is required, the container will identify that an instance of IStudent is required. So it will instantiate the registered instance of IStudent and pass it as paramter while instantiating HomeController class.

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

Also, note that what you are referring to is 'Dependency Injection' (which is one specific form of IoC). There are other forms of IoC (e.g. callbacks, Observer pattern, etc.).

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

EDIT:Don't forget to read the popular articleon DI.

编辑:不要忘记阅读有关 DI的流行文章

回答by K D

In IoC you need to register the interface and a class which is implementing the interface. So once you register then whenever you have signature like above IoC will automatically create an instance of IStudent implemented class and inject it to the object while initializing the controller. It saves the time and efforts to declare the members. In above case you just have one to declare, but it could be more in numbers and those all could need few more instances to pass to the controller. Once we register those all correctly IoC do its work thereafter. Infact we can decide the Scope/Lifetime of the injected members. It can be PerInstance/Per Request/ Or Singleton.

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

There are saveral IoC frameworks available its up to you which one you want to go with.

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

回答by TalentTuner

In general it is called injecting the dependencies of a class , think about a class or to be precise a GOD class which handles all the stuff like ( Validating user input , coordinating with Database , generating HTML output etc) so you keep all your code in single place or you can say you develop all of your software using single class , isn't that good?

一般来说,它被称为注入类的依赖关系,考虑一个类,或者准确地说是一个 GOD 类,它处理所有的事情,比如(验证用户输入,与数据库协调,生成 HTML 输出等),这样你就可以将所有代码保存在一个地方,或者你可以说你使用一个类开发你的所有软件,那不是很好吗?

Answer depends upon the way you organize the things , do you think , organizing things where it belongs is beneficial than you will see the problem in the above GOD class.

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

So in terms of OOPS , A single class shd have a single reason to be changed but it is required to get the work done than it shd take help from the services.

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

And your HomeController is doing the same thing since it does not want to be overworked , it has asked Student object to handle student.

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

回答by phnkha

When a new HomeController object is constructed by IOC resolver, it will take an object that implements IStudent interface provided by the IOC container(the one you registered) via its constructor.

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

You can read more about Constructor Injection here.

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