Инъекция конструктора-мы также вводим заводы?
После прослушивания разговоров о чистом коде я пришел к пониманию того, что мы должны использовать фабрики для создания объектов. Так, например, если у House есть Door и у Door есть DoorKnob, в HouseFactory мы создаем новый DoorKnob и передаем его конструктору Door, а затем передаем этот Новый Door объект конструктору House.
Но как насчет класса, который использует House (скажем, имя класса ABC)? Это будет зависеть от HouseFactory, верно? Так что мы проходим HouseFactory в конструкторе ABC? Не придется ли нам таким образом пройти через множество фабрик в конструкторе?
3 ответа:
Оставаясь с дверью и дверной ручкой, вы не вводите фабрику - вы вводите саму ручку:
На этом уровне не видно никаких фабрик. Дом, с другой стороны, зависит от двери, но не от дверной ручки:public class Door { private readonly DoorKnob doorKnob; public Door(DoorKnob doorKnob) { if (doorKnob == null) throw new ArgumentNullException("doorKnob"); this.doorKnob = doorKnob; } }public class House { private readonly Door door; public House(Door door) { if (door == null) throw new ArgumentNullException("door"); this.door = door; } }Это сохраняет опции открытыми до тех пор, пока, наконец, вы не будете иметь , чтобы составить все в корне композиции приложения :
var house = new House(new Door(new DoorKnob()));Вы можете использовать контейнер DI для создания на этом уровне, но вам это не нужно. Нет задействованы заводы.
Если вы вводите слишком много фабрик, это запах кода, называемый конструктором over-injection, который указывает, что ваш класс делает слишком много.
Многие контейнеры предоставляют функцию, называемую автозаводами. Это означает, что они генерируют фабрики типа
Замок Виндзор имеет расширенную функцию под названиемтипизированные заводские средства , которая генерирует реализации Заводского интерфейса на лету.Func<T>автоматически, если они знают, как генерироватьT.Есть также порт типизированных фабрик для Unity в проектеTecX .
Если вы в конечном итоге используете Unity, я недавно реализовал эквивалент типизированных фабрик Castle Windsor для Unity. Вы можете найти проект по адресу https://github.com/PombeirP/Unity.TypedFactories , и пакет NuGet в http://nuget.org/packages/Unity.TypedFactories .
Используется следующее:
unityContainer .RegisterTypedFactory<IFooFactory>() .ForConcreteType<Foo>();Вам просто нужно создать интерфейс IFooFactory с помощью метода, возвращающего IFoo, а остальное сделает за вас библиотека. Вы можете решить IFooFactory и использовать его для создания объектов IFoo сразу.