В большинстве случаев я чаще всего склоняюсь к использованию "инъекции ублюдка". Когда у меня есть "правильный" конструктор инъекций зависимостей:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
Но тогда для классов, которые я намереваюсь использовать публичные API (классы, которые будут потреблять другие команды разработчиков), я никогда не смогу найти лучший вариант, чем написать конструктор "bastard" по умолчанию Вероятная необходимая зависимость:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
Очевидным недостатком здесь является то, что это создает статическую зависимость от DefaultThingSource; в идеале, такой зависимости не будет, и потребитель всегда будет вводить любой желаемый IThingSource. Однако это слишком сложно использовать; потребители хотят обновить ThingMaker и приступить к работе над Things, а затем через несколько месяцев внедрить что-то еще, когда возникнет такая необходимость. На мой взгляд, это оставляет несколько вариантов:
- Опустить конструктор ублюдка; заставить потребителя ThingMaker понимать IThingSource, понимать, как ThingMaker взаимодействует с IThingSource, находить или писать конкретный класс, а затем вставлять экземпляр в свой вызов конструктора.
- Опустить конструктор bastard и предоставить отдельный factory, контейнер или другой класс/метод начальной загрузки; каким-то образом заставить потребителя понять, что им не нужно писать собственный IThingSource; заставить потребителя ThingMaker находить и понимать factory или загрузчик и использовать его.
- Храните конструктор bastard, позволяя потребителю "обновлять" объект и работать с ним и справляться с дополнительной статической зависимостью от DefaultThingSource.
Мальчик, № 3 уверен, кажется привлекательным. Есть ли другой, лучший вариант? # 1 или # 2 просто не кажется нужным.