с постоянно увеличивающимся списком параметров. Поскольку "Контейнер" - это мой контейнер для внедрения зависимостей, почему я не могу просто сделать это:
publicMyClass(Container con)
для каждого класса? Каковы недостатки? Если я делаю это, создается ощущение, что я использую прославленную статику. Пожалуйста, поделитесь своими мыслями о IoC и безумии внедрения зависимостей.
Переведено автоматически
Ответ 1
Вы правы в том, что если вы используете контейнер в качестве локатора служб, это более или менее прославленная статическая фабрика. По многим причинам я считаю это антишаблоном (также смотрите Этот отрывок из моей книги).
Одно из замечательных преимуществ внедрения конструктора заключается в том, что оно делает нарушения принципа единой ответственности совершенно очевидными.
Когда это происходит, пришло время провести рефакторинг для фасадных сервисов. Короче говоря, создайте новый, более детализированный интерфейс, который скрывает взаимодействие между некоторыми или всеми детализированными зависимостями, которые вам требуются в данный момент.
Ответ 2
Я не думаю, что конструкторы ваших классов должны ссылаться на период вашего контейнера IOC. Это представляет собой ненужную зависимость между вашим классом и контейнером (тип зависимости, которого IOC пытается избежать!).
Ответ 3
Сложность передачи параметров не является проблемой. Проблема в том, что ваш класс делает слишком много, и его следует еще больше разбивать.
Внедрение зависимостей может служить ранним предупреждением о том, что классы становятся слишком большими, особенно из-за возрастающей сложности передачи всех зависимостей.
Ответ 4
Проблема :
1) Конструктор с постоянно увеличивающимся списком параметров.
2) Если класс наследуется (например: RepositoryBase), то изменение сигнатуры конструктора вызывает изменения в производных классах.
Решение 1
Передать IoC Container конструктору
Почему
Список параметров больше не увеличивается
Сигнатура конструктора становится простой
Почему бы и нет
Ваш класс тесно связан с контейнером IoC. (Это вызывает проблемы, когда 1. вы хотите использовать этот класс в других проектах, где вы используете другой контейнер IoC. 2. вы решили сменить контейнер IoC)
Делает ваш класс менее описательным. (Вы не можете действительно посмотреть на конструктор класса и сказать, что ему нужно для функционирования.)
Класс потенциально может получить доступ ко всем сервисам.
Решение 2
Создайте класс, который группирует все службы, и передайте его конструктору
publicabstractclassEFRepositoryBase { publicclassDependency { public DbContext DbContext { get; } public IAuditFactory AuditFactory { get; }
Добавление новой зависимости к классу не влияет на производные классы
Класс не зависит от контейнера IoC
Класс является описательным (в аспекте его зависимостей). По соглашению, если вы хотите знать, от какого класса A зависит, эта информация накапливается в A.Dependency
Подпись конструктора становится простой
Почему бы и нет
необходимо создать дополнительный класс
регистрация служб становится сложной (Вам нужно регистрировать каждую X.Dependency отдельно)
Концептуально то же самое, что передача IoC Container
..
Решение 2 - это всего лишь сырое, хотя, если есть веские аргументы против него, то был бы признателен за описательный комментарий