2015-03-25 3 views
1

У меня есть контроллер, который принимает DbContext, а тот, кто этого не делает. Т.е. ,:Как использовать конструктор с параметрами от одного без параметров

public CalendarController() 
{ 
    var db = new DbContext(); 
    CalendarController(db); // <= Not allowed 
} 

public CalendarController(IDbContext db) 
{ 
    _calendarManager = new CalendarManager(db); 
    _userManager = new UserManager(db); 
    _farmingActionManager = new FarmingActionManager(db); 
    _cropManager = new CropManager(db); 
} 

К сожалению, выше, дает ошибку на линии CalendarController(db):

Выражение обозначает «тип», в котором, как ожидалось а «переменная», «значение» или «метод group`

Можно ли назвать один конструктор из другого? Я не хочу дублировать весь код.

+0

Видимо, вы пытаетесь внедрить анти-шаблон Bastard. Нет! не делайте этого. –

+0

@SriramSakthivel Не могли бы вы объяснить, что такое Bastard Injection Anti-Pattern? Я делаю это таким образом, так как мне нужен тот же экземпляр DbContext для экземпляра контроллера, я не нашел лучшего решения. 'autofac' был многообещающим, но он по-прежнему выдавал ошибку при использовании нескольких экземпляров DbContext в одном запросе. –

+0

Вы полностью не понимаете DI. когда вы используете ключевое слово 'new', за исключением корня композиции (объекты-значения - исключение), вы нарушаете DI. Вы обновляете «CalendarManager», «UserManager» и т. Д., Которые вы должны действительно воспринимать как параметр конструктора (как некоторый интерфейс). Тем не менее, Bastard Injection - это то, что происходит, когда зависимость является Foreign Default (реализована в другой сборке), которая была введена по умолчанию. 'DbContext' - иностранная зависимость (я считаю); вы не должны быть тесно связаны с потребителем с зависимостью в другой сборке. –

ответ

7

Вы должны приковать к конструктору, как это:

public CalendarController() : this(new DbContext()) 
{ 
} 

Это синтаксис для сцепления с любого конструктора в том же классе - он не должен быть из без параметров одного до параметризованных один, хотя он должен быть другим :)

Обратите внимание, что это происходит перед телом конструктора, поэтому сначала вы ничего не можете сделать, хотя вы можете вызвать статические методы для вычисления аргументов другому конструктору. Вы не можете использовать методы экземпляра. Так что это нормально:

public Foo() : this(GetDefaultBar()) 
{ 
} 

public Foo(int bar) { ... } 

private static int GetDefaultBar() { ... } 

Но это не так:

public Foo() : this(GetDefaultBar()) 
{ 
} 

public Foo(int bar) { ... } 

private int GetDefaultBar() { ... } 

Синтаксис цепи конструктору в базовом классе аналогична:

public Foo() : base(...) 

Если вы не» t укажите либо : base(...), либо : this(...), то компилятор неявно добавляет вам : base(). (Это не обязательно связано с конструктором без параметров, он может иметь необязательные параметры.)

+0

Работает. Спасибо. –

+0

@ ErwinRooijakkers Ответ Джона полна хорошей информации. Хорошо знать. Но, поскольку вы отметили вопрос с помощью инъекции зависимостей, я рекомендую не падать в Bastard Injection. Рассмотрите мои комментарии чуть ниже своего сообщения. –

Смежные вопросы