Является ли это хорошим примером антипаттерна Bastard инъекции?

Я вижу, как ведущие разработчики пишут подобный код, и после прочтения книги Марка Симанна "Внедрение зависимостей в .NET" мне интересно, является ли конкретное "новое" "чужим", таким образом, "Незаконное внедрение"??

public class SessionInitServiceManager
{
    protected readonly ICESTraceManager _traceManager;
    protected readonly ILogger _logger;
    protected readonly IAggregateCalls _aggregator;
    protected readonly IMultiCoreRepository _repository;

    public SessionInitServiceManager(ICESTraceManager traceManager,
                                     ILogger logger,
                                     IAggregateCalls aggregator,
                                     IMultiCoreRepository repository)
    {
        _traceManager = traceManager;
        _logger = logger;
        _aggregator = aggregator;
        _repository = repository;
    }

    public SessionInitServiceManager() : this(new CESTraceManager(),
                                              new Logger("BusinessServices.authenticateUser"),
                                              new Aggregator(),
                                              new RepositoryFactory().BuildMultiCoreRepository()) { }

person Tom Stickel    schedule 05.12.2011    source источник
comment
Между прочим, четыре параметра раздвигают предел разумного DI (автор утверждает, что его ограничение обычно равно четырем), потому что это заставляет вас задуматься о том, не нарушает ли SessionInitServiceManager SRP. Переход в другой класс менеджеров также предполагает, что это может иметь место.   -  person RichK    schedule 06.12.2011
comment
Да, я помню, читал, что 3-4 - это общий предел. Любые хорошие примеры того, как избежать этой новой проблемы с или без контейнера IOC, такого как единство. ?   -  person Tom Stickel    schedule 06.12.2011
comment
Ответ зависит от того, определена ли какая-либо из реализаций «по умолчанию» в той же библиотеке или в другой библиотеке. stackoverflow.com/questions/6733667/   -  person Mark Seemann    schedule 06.12.2011
comment
@MarkSeemann Хорошо, это проясняет для меня ситуацию. Спасибо, Марк! Я наслаждаюсь вашей книгой BTW. Спасибо!   -  person Tom Stickel    schedule 06.12.2011


Ответы (2)


Это наверняка выглядит как классический пример Bastard Injection. Причина в том, что у вас есть то, что выглядит как четыре внешних значения по умолчанию. Внешнее значение по умолчанию относится к значению по умолчанию, в котором тип исходит из другого модуля/проекта/DLL. Я бы пропил включить пространство имен в это определение, потому что пространства имен могут обозначать границы, в которых в будущем вы сделаете прорыв в свой собственный модуль. Это больше связано с тем, чтобы помнить об этом, когда вы решите использовать локальное значение по умолчанию (буду ли я разделить это на отдельный модуль в будущем?).

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

person LCarter    schedule 06.12.2011

Я случайно позаимствовал эту книгу «Внедрение зависимостей в .NET» у друга. Я вижу, что вы говорите. Я верю, что это "ублюдочная инъекция". Это жестокий термин, но я полагаю, что он подходит, ведь ColdFusion (кашель) имеет тег «CFABORT» как часть языка.

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

В общем, прежде чем мы начнем, давайте кое-что уберем с пути:

Внедрение зависимостей! = Использование контейнера IoC"

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

 public class HomeController
 {
    private readonly IExampleService _service;

    public HomeController()
    {
      _service = Container.Instance.Resolve<IExampleService>();
    }

    public ActionResult Index()
    {
      return View(_service.GetSomething());
    }
 }
person Tom Stickel    schedule 15.02.2012
comment
Внутри конструктора по умолчанию вы на самом деле используете антишаблон Service Locator, откуда вы знаете, что контейнер будет иметь IExampleService для вас? А если нет? в методе Index NullArgumentException, и во время разработки он выглядит нормально. Это не использование контейнера IoC, это неправильное применение DI - person Ricardo Rodrigues; 19.02.2013