t4mvc: не может наследовать класс контроллера, у которого нет конструктора по умолчанию? - PullRequest
9 голосов
/ 18 июля 2011

Я использую 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, который является шаблоном UnitOfWork для добавления функциональности CRUD):

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

Когда я запускаю свой шаблон t4, генерируется этот код:

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

Но это дает мне ошибку во время компиляции:

MyApp.EntityController не содержит конструктор, который принимает 0 аргументов

Как я могу решить эту проблему?

Ответы [ 3 ]

7 голосов
/ 27 июня 2012

Я хотел, чтобы базовый класс контроллера был абстрактным, а его конструктор защищен и параметризован. Обошел эту проблему, добавив пустой конструктор в 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 генерировать компилируемый код. Кажется, ошибка в том, что он всегда пытается сгенерировать пустой (без параметров) конструктор для классов контроллера.

Надеюсь, это кому-нибудь поможет.

2 голосов
/ 19 июля 2011

Я вижу проблему, и это сводится к тому, что T4MVC не совсем правильно поступает при работе с общими классами.Обычно он генерирует ctor по умолчанию для него в частичном классе, но тот факт, что он является универсальным, сбрасывает его.

Вы можете обойтись, просто добавив ctor по умолчанию самостоятельно, например,

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

    // etc...
}
0 голосов
/ 13 ноября 2015

Я заметил кое-что очень странное:

Я добавил пустой конструктор в базовый класс, но без throw new NotImplementedException();, и он отлично работает.

Но вот странныйДело в том, что при вызове контроллера, если у меня есть URL-адрес, такой как / {controller}? params (для стандартного действия устанавливается значение Index в RouteConfig), вызывается частный контроллер без параметров в базовом классе.Но когда у меня есть URL-адрес типа / {controller} / {action}? Params , тогда вызывается конструктор с параметрами.

...