为什么MVC提供的Default AccountController中有2个构造函数?

时间:2009-12-30 11:07:33

标签: asp.net-mvc dependency-injection constructor

这是框架生成的默认 AccountController.cs

public class AccountController : Controller
{
    public IFormsAuthentication FormsAuth { get; private set; }
    public IMembershipService MembershipService { get; private set; }

    public AccountController()
        : this(null, null)
    {
    }
    public AccountController(IFormsAuthentication formsAuth, IMembershipService membershipService)
    {
        FormsAuth = formsAuth ?? new FormsAuthenticationService();
        MembershipService = membershipService ?? new AccountMembershipService();

        //---
    }

这很容易理解。

public AccountController(IFormsAuthentication formsAuth, 
        IMembershipService membershipService)
    {
        FormsAuth = formsAuth ?? new FormsAuthenticationService();
        MembershipService = membershipService ?? new AccountMembershipService();
    }

这是什么?它的目的是什么?它是特定于帐户控制器还是其他控制器的要求?而且,我为什么要将它纳入我的项目?

public AccountController()
        : this(null, null)
    {
    }

他们似乎在其他两个地方使用这种类型的构造函数。

感谢您的帮助

3 个答案:

答案 0 :(得分:7)

这实际上是 Bastard Injection 反模式的实现。

我们的想法是支持构造函数注入以允许依赖注入(DI),同时仍然提供默认行为的默认构造函数。

没有必要使用默认构造函数,但如果省略它,则必须提供自定义IControllerFactory,因为DefaultControllerFactory假定所有控制器都有默认构造函数。

ASP.NET MVC是在构建DI时考虑到的,但我想为了保持简单,Bastard Injection模式用于项目模板,以避免强制开发人员使用特定的IControllerFactory。

答案 1 :(得分:0)

  1. 如果使用DI框架(如Unity)并通过容器激活控制器,则可能找不到依赖项并使用默认构造函数(在本例中)。

  2. 如果你想使用泛型,像... where T : IController, new()那样你需要一个默认的构造函数。

答案 2 :(得分:0)

拥有默认(无参数)构造函数的另一个原因是Reflection

  

System.Reflection命名空间中的类与Type一起,允许您获取有关已加载的assemblies及其中定义的类型的信息,例如classesinterfacesvalue types。您还可以使用反射在运行时创建类型实例,并调用和访问它们。

有时可能需要创建该类型的临时对象以反映其属性或方法,但不希望或需要创建真实对象的开销 - 特别是如果需要访问数据库或远程服务,例如。