Я вижу, как ведущие разработчики пишут подобный код, и после прочтения книги Марка Симанна "Внедрение зависимостей в .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()) { }
Ответ 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());
}
}