Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Tom StickelОтветов: 2

Я вижу, как ведущие разработчики пишут подобный код, и после прочтения книги Марка Симанна "Внедрение зависимостей в .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()) { }
  • Между прочим, четыре параметра раздвигают предел разумного DI (автор утверждает, что его ограничение обычно равно четырем), потому что это заставляет вас задуматься о том, не нарушает ли SessionInitServiceManager SRP. Переход в другой класс менеджеров также предполагает, что это может иметь место. RichK 06.12.2011
  • Да, я помню, читал, что 3-4 - это общий предел. Любые хорошие примеры того, как избежать этой новой проблемы с или без контейнера IOC, такого как единство. ? Tom Stickel 06.12.2011
  • Ответ зависит от того, определена ли какая-либо из реализаций "по умолчанию" в той же библиотеке или в другой библиотеке. stackoverflow.com/questions/6733667/ Mark Seemann 06.12.2011
  • @MarkSeemann Хорошо, это проясняет для меня ситуацию. Спасибо, Марк! Я наслаждаюсь вашей книгой BTW. Спасибо! Tom Stickel 06.12.2011

constructordependency-injectioninversion-of-control

Ответы

Ответ 1 · рейтинг 7 · LCarter

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

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

Ответ 2 · Tom Stickel

Я случайно позаимствовал эту книгу "Внедрение зависимостей в .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());
    }
 }

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы