t4mvc:无法继承没有默认构造函数的控制器类?

时间:2011-07-18 09:34:47

标签: constructor controller t4mvc

我正在使用T4MVC和MVC2。

我有以下构建基块:

  1. 一个简单的实体接口,它定义每个POCO实体必须具有long Id属性:

    public interface IEntity
    {
        public long Id;
    }
    
  2. 一个简单的POCO类,它实现IEntity接口并具有一些字符串属性:

    public class CD : IEntity
    {
        public long Id { get; set; }
    
        public long Name { get; set; }
    }
    
  3. 基本控制器:

    public abstract class EntityController<T> : Controller where T : class, global::IEntity
    {
        public EntityController(IEntityManager<T> manager);
    }
    
  4. 我在CDController中使用此基本控制器(其中CDManager实现了IEntityManager接口,这是一个用于添加CRUD功能的UnitOfWork模式):

    public partial class CDController : EntityController<CD>
    {
        public CDController() : base(new CDManager()) { }
    }
    
  5. 当我运行我的t4模板时,会生成以下代码:

    namespace MyApp.Web.Controllers {
        public partial class CDController {
            [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
            protected CDController(Dummy d) { }
    

    但是这在编译期间给了我一个错误:

      

    MyApp.EntityController&LT; CD&GT;不包含带0参数的构造函数

    我该如何解决这个问题?

3 个答案:

答案 0 :(得分:7)

我希望控制器基类是抽象的,并且它的构造函数受到保护和参数化。通过向ControllerBase添加一个空的构造函数来解决此问题,该构造函数抛出NotImplementedException。

感觉不太对,但它完成了工作。唯一的问题是当与依赖注入相结合时,将调用错误的构造函数 - 因为它会抛出异常,应用程序将会崩溃。

代码:

public abstract class ControllerBase : Controller
{
    protected object AlwaysSupply { get; private set; }

    public ControllerBase()
    {
        throw new NotImplementedException();
    }

    public ControllerBase(object alwaysSupply)
    {
        AlwaysSupply = alwaysSupply;
    }
}

这将导致T4MVC生成可编译的代码。错误似乎是它总是试图为控制器类生成一个空(无参数)构造函数。

希望这有助于某人。

答案 1 :(得分:2)

我看到了这个问题,并且归结为T4MVC在处理泛型类时没有做正确的事情。通常它会在部分类中为它生成一个默认的ctor,但事实上它是通用的将它抛弃。

你应该能够通过自己添加默认的ctor来解决这个问题,例如

public abstract partial class EntityController<T> : Controller where T : class, IEntity {
    public EntityController() { }

    // etc...
}

答案 2 :(得分:0)

我注意到一些非常奇怪的东西:

我已经将空构造函数添加到基类中,但是没有throw new NotImplementedException();并且它工作正常。

但是这是奇怪的事情,如果我有一个网址就叫控制器   / {controller}?params (在RouteConfig中将默认操作设置为Index)调用基类上的无参数私有控制器。 但是当我有一个像 / {controller} / {action}?params 的网址时,会调用带参数的构造函数。