问题
I am using T4MVC with MVC2.
I have the following building blocks:
A simple entity interface which defines that every POCO entity must have a
long Id
property:public interface IEntity { public long Id; }
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; } }
A base controller:
public abstract class EntityController<T> : Controller where T : class, global::IEntity { public EntityController(IEntityManager<T> manager); }
I use this base controller in my
CDController
(whereCDManager
implements theIEntityManager
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