t4mvc : Cannot inherit a controller class which has no default constructor?

谁说胖子不能爱 提交于 2019-12-01 14:41:09

问题


I am using T4MVC with MVC2.

I have the following building blocks:

  1. A simple entity interface which defines that every POCO entity must have a long Id property:

    public interface IEntity
    {
        public long Id;
    }
    
  2. A simple POCO class which implements the IEntity interface and has some string properties:

    public class CD : IEntity
    {
        public long Id { get; set; }
    
        public long Name { get; set; }
    }
    
  3. A base controller:

    public abstract class EntityController<T> : Controller where T : class, global::IEntity
    {
        public EntityController(IEntityManager<T> manager);
    }
    
  4. I use this base controller in my CDController (where CDManager implements the IEntityManager interface, which is a UnitOfWork pattern to add CRUD functionality):

    public partial class CDController : EntityController<CD>
    {
        public CDController() : base(new CDManager()) { }
    }
    

When I run my t4 template, this code is generated:

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

But this gives me an error during compilation:

MyApp.EntityController<CD> does not contain a constructor that takes 0 arguments

How can I solve this?


回答1:


I wanted by controller base class to be abstract and it's constructor protected and parametrized. Got around this issue by adding a blank constructor to ControllerBase that throws a NotImplementedException.

Doesn't quite feel right but it gets the job done. Only issue is when combined with dependency injection the wrong constructor will be called - since it throws an exception the app will bum out.

Code:

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

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

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

This will cause T4MVC to generate compilable code. The fault seems to be it always tries to generate a blank (no parameters) constructor for controller classes.

Hope this helps someone.




回答2:


I see the problem, and it comes down to T4MVC not quite doing the right thing when dealing with generic classes. Normally it would generate a default ctor for it in a partial class, but the fact that it's generic is throwing it off.

You should be able to work around simply by adding a default ctor yourself, e.g.

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

    // etc...
}



回答3:


I've noticed something very odd:

I've added the empty constructor to the base class, but without the throw new NotImplementedException(); and it works fine.

But here's the odd thing, when calling the controller if I have an url like /{controller}?params (default action being set to Index in the RouteConfig) the parameterless private controller on the base class is called. But when I have an url like /{controller}/{action}?params then the constructor with parameters is called.



来源:https://stackoverflow.com/questions/6730989/t4mvc-cannot-inherit-a-controller-class-which-has-no-default-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!