Я пишу библиотеку, которая будет предоставлять набор общедоступных типов своим потребителям.
Я хочу сделать типы из этой библиотеки удобными для внедрения зависимостей. Это означает, что каждый класс должен иметь конструктор, с помощью которого можно указать каждую отдельную зависимость инициализируемого объекта. Я также хочу, чтобы библиотека придерживалась принципа соглашения по конфигурации. Это означает, что если потребитель хочет поведение по умолчанию, он может использовать конструктор без параметров, и объект каким-то образом создаст зависимости для себя.
В примере (C#):
public class Samurai {
private readonly IWeapon _weapon;
// consumers will use this constructor most of the time
public Samurai() {
_weapon = ??? // get an instance of the default weapon somehow
}
// consumers will use this constructor if they want to explicitly
// configure dependencies for this instance
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
}
Моим первым решением было бы использование шаблона локатора сервисов.
Код будет выглядеть так:
...
public Samurai() {
_weapon = ServiceLocator.Instance.Get();
}
...
Однако у меня есть проблема с этим. Сервисный локатор был помечен как антишаблон (ссылка), и я полностью согласен с этими аргументами. С другой стороны, Мартин Фаулер выступает за использование шаблона локатора сервисов именно в этой ситуации (библиотечные проекты) (ссылка). Я хочу быть осторожным и исключить возможную необходимость переписать библиотеку после того, как выяснится, что локатор сервисов действительно был плохой идеей.
Итак, в заключение — считаете ли вы, что сервисный локатор подходит для этого сценария? Должен ли я решить свою проблему совершенно по-другому? Любая мысль приветствуется...