Как правильно использовать инъекцию зависимостей?


Простой случай: У меня есть интерфейс для регистрации сообщений, например:

public interface ILogger
{
   void Log(string message);
}

И, возможно, три различных класса реализуют этот интерфейс.

Теперь я мог бы написать в одном месте, строка для Ди, что-то вроде:

kernel.Bind<ILogger>().To<ConsoleLogger>();

Мой вопрос в том, как использовать этот интерфейс во многих классах, но без введения всех через конструктор. Потому что у нас может быть так много различных интерфейсов, которые мы хотим использовать, и объявление этого конструктора класса может быть беспорядочным.

4 3

4 ответа:

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

При внедрении зависимостей использование внедрения свойств вне унаследованных сценариев считается плохой формой. Ввод значения через свойства предполагает его необязательность и, следовательно, не является реальной зависимостью.

Если у вас есть тип, который имеет множество зависимостей конструктора, это может означать, что вам нужно сделать некоторый рефакторинг. Возможно, некоторые типы используются вместе и могут быть преобразованы в их собственный компонент. В любом случае, если вы используете фреймворк IoC, такой как Ninject, действительно ли это так неважно, сколько параметров конструктора принимает тип? Контейнер сделает впрыску для вас независимо.

Хотя то, что говорит @LukeMcGregor, в целом верно, логгер выглядит как сквозная проблема, и также может быть решен через AOP, Если вы не хотите загрязнять каждый конструктор ILogger. Ninject, кажется, поддерживает AOP через ninject.увеличение.Перехват .

Можно реализовать свойство ILogger Logger { get; set;} в классах и использовать функцию внедрения свойств, поддерживаемую большинством контейнеров IoC.