2016-04-26 2 views
-3

Я читаю через ASP.NET 5 docs и задыхаюсь от главы инъекции зависимостей.ASP.NET 5/Core 1 Инъекция зависимостей: плохой дизайн или плохая документация?

Я рекомендовал писать свои контроллеры так:

public class MyController: Controller 
{ 
    private readonly MyService _myService; 

    public MyController(MyService myService) 
    { 
     _myService = myService; 
    } 

    public IActionResult Index() 
    { 
     // use _myService 
    } 
} 

Короткий и прямой вариант не рекомендуется:

public class MyController : Controller 
{ 
    public IActionResult Index() 
    { 
     var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService)); 
    } 
} 

The given reason потому, что якобы рекомендуемая версия ...

[...] дает классы, которые легче тестировать (см. Тестирование) и более слабо связаны.

Связанная глава тестирования не проливает свет на эту странную инструкцию.

Я не смотрел на источники, но я предполагаю, какие конструкции контроллер использует HttpContext.RequestServices.GetService для доставки зависимости? Очевидно, что тест может настроить различную реализацию для тестирования и, очевидно, , что - это вся суть рамки DI, правильно?

Колос (MyService)HttpContext.RequestServices.GetService(typeof(MyService)) достаточно плох, но маленький помощник может исправить это (было очень просто Get<MyService>()).

Но этот чрезмерный беспорядок рекомендуется для практически каждого контроллера и более беспокоит.

Это тем более непонятно, как там уже есть основа Microsoft DI с правильным использованием, MEF:

public class MyController : Controller 
{ 
    [Import] 
    private MyService _myService; 

    public IActionResult Index() 
    { 
     // use _myService 
    } 
} 

Почему хотя бы не просто принять, что один? Что тут происходит?

+0

Не подходит тип вопроса на SO. Перед публикацией прочитайте FAQ/справочный центр. Основополагающие мнения не являются правильным типом вопроса для SO. Просто предложение для вашего «вопроса»: ваша версия скрывает зависимости, и во время модульного теста невозможно узнать, какие зависимости у класса есть, тогда как конструктор, который вы видите, плюс ваши типы, зависит от конкретного контейнера, тогда как конструктор этого не делает. – Tseng

+1

Это просто плохая документация :) – Steven

ответ

2

Это не конкретное решение ASP.NET Core. Вот как работает примерно каждый каркас DI. Наиболее распространенным подходом является наличие всех зависимостей контроллера в качестве параметров конструктора. Это дает понять, какие службы использует контроллер. Существует несколько альтернативных решений, но основная идея остается неизменной, и для них есть несколько плюсов и минусов.

Очевидно, что тест может установить различную реализацию для тестирования, и ясно, что это весь смысл структуры DI, правильно?

Эта линия не ясна для меня. Как вы думаете, «целая точка рамок DI»? Эта строка предлагает использовать ее только для того, чтобы вы могли использовать другую реализацию для тестирования.

Но этот чрезмерный беспорядок рекомендуется в основном для каждого контроллера и более беспокоит.

Чрезмерный беспорядок? Что делать, если я хочу использовать MyService в двух (или более) функциях?Должен ли я использовать это:

public class MyController : Controller 
{ 
    public IActionResult Index() 
    { 
     var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService)); 
    } 

    public IActionResult Index2() 
    { 
     var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService)); 
    } 
} 

Или я должен выбрать решение, где я устанавливаю его в конструкторе? Мне кажется очевидным выбором для меня. В таком маленьком примере он может выглядеть как беспорядок, но добавить к нему 10 строк кода, и вы едва заметите небольшой конструктор и некоторые объявления переменных.

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

Наконец-то вы предлагаете впрыск имущества. Это допустимое решение. Но часто используемый аргумент против него заключается в том, что он скрывает зависимость. Если вы определяете его как параметр в конструкторе, вы не можете скрыть его. Кроме того, из-за этого у многих каркасов DI даже не поддерживается поддержка свойств или методов.

Если вы хотите использовать MEF в своем проекте, вы можете это сделать. Но он должен, на мой взгляд, не быть базой DI DI для ASP.NET. То, что доступно сейчас, более чем достаточно для выполнения большинства задач. Если вам нужна дополнительная функциональность, вы всегда можете использовать различные рамки DI, такие как StructureMap или AutoFac.

В конце концов, все сводится к тому, что работает для вас. Но заявить, что это либо плохой дизайн, либо плохая документация, это просто неправильно. Вы, конечно, можете доказать, что я ошибаюсь. Вы могли бы улучшить документацию ASP.NET и/или доказать, что концепция инверсии управления неверна и предлагает лучшее решение.

+0

Я согласен с тем, что это традиция. Я знал только MEF, поэтому я обвинил ASP.NET. Я все еще считаю, что все, что создает беспорядок, похоже на плохой дизайн, но я понимаю, что это мнение столь же верно, как и ваше. – John

+0

Можете ли вы изменить «Entity Framework» на MEF в своем ответе? По какой-то причине мои изменения, похоже, отклоняются. – John