Внедрение в конструктор - Мы также вводим фабрики? - PullRequest
9 голосов
/ 24 января 2012

После прослушивания Чистых разговоров по коду я понял, что мы должны использовать фабрики для составления объектов. Так, например, если House имеет Door, а Door имеет DoorKnob, в HouseFactory мы создаем новый DoorKnob и передаем его конструктору Door, а затем передать этот новый Door объект в конструктор House.

Но как насчет класса, который использует House (скажем, имя класса ABC) ? Это будет зависеть от HouseFactory, верно? Так мы передаем HouseFactory в конструкторе ABC? Разве мы не должны таким образом передать множество фабрик в конструктор?

Ответы [ 3 ]

9 голосов
/ 24 января 2012

Следуя примеру с дверью и дверной ручкой, вы не вводите фабрику - вы вводите саму ручку DooKnob:

public class Door
{
    private readonly DoorKnob doorKnob;

    public Door(DoorKnob doorKnob)
    {
        if (doorKnob == null)
            throw new ArgumentNullException("doorKnob");

        this.doorKnob = doorKnob;
    }
}

На этом уровне не видно ни одной фабрики.

Домс другой стороны, зависит от Door, но не от DoorKnob:

public class House
{
    private readonly Door door;

    public House(Door door)
    {
        if (door == null)
            throw new ArgumentNullException("door");

        this.door = door;
    }
}

Это оставляет опции открытыми до тех пор, пока, наконец, у вас не будет для составления всего в корне Composition приложения:

var house = new House(new Door(new DoorKnob()));

Вы можете использовать DI-контейнер для создания композиций на этом уровне, но это не обязательно.Фабрики не задействованы.

1 голос
/ 24 января 2012

Если вы добавляете слишком много фабрик, которые имеют запах кода, называемый чрезмерное внедрение конструктора , которое указывает, что ваш класс делает слишком много.

Многие контейнеры предоставляют функцию, называемую автофабриками.Это означает, что они генерируют фабрики типа Func<T> автоматически, если они знают, как генерировать T.

В Castle Windsor имеется расширенная функция, называемая Типизированная фабрика объектов , которая генерирует реализации интерфейса фабрики.на лету.

В проекте TecX .

есть также порт типизированных фабрик для Unity.
0 голосов
/ 07 декабря 2012

Если вы в конечном итоге используете Unity, я недавно внедрил аналог фабрики Castle Windsor Typed для Unity. Вы можете найти проект в https://github.com/PombeirP/Unity.TypedFactories, и пакет NuGet в http://nuget.org/packages/Unity.TypedFactories.

Используется следующее:

unityContainer
    .RegisterTypedFactory<IFooFactory>()
    .ForConcreteType<Foo>();

Вам просто нужно создать интерфейс IFooFactory с методом, возвращающим IFoo, а все остальное сделает за вас библиотека. Вы можете разрешить IFooFactory и сразу использовать его для создания объектов IFoo.

...