Инъекция конструктора-мы также вводим заводы?
После прослушивания разговоров о чистом коде я пришел к пониманию того, что мы должны использовать фабрики для создания объектов. Так, например, если у 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 сразу.