Constructor Injection - Do we inject factories as well?
Asked Answered
B

3

9

After listening to the Clean Code Talks, I came to understand that we should use factories to compose objects. So, for example, if a House has a Door and a Door has a DoorKnob, in HouseFactory we create a new DoorKnob and pass it to the constructor of Door, and then pass that new Door object to the constructor of House.

But what about the class that uses the House (say the class name is ABC)? It will depend on the HouseFactory, right? So do we pass the HouseFactory in the constructor of ABC? Won't we have to pass a whole lot of factories in the constructor that way?

Bergschrund answered 24/1, 2012 at 0:9 Comment(0)
E
10

Staying with the Door and DoorKnob example, you don't inject a factory - you inject the DooKnob itself:

public class Door
{
    private readonly DoorKnob doorKnob;

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

        this.doorKnob = doorKnob;
    }
}

No factories are in sight in this level.

House, on the other hand, depends on Door, but not on DoorKnob:

public class House
{
    private readonly Door door;

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

        this.door = door;
    }
}

This keeps options open until at last you have to compose everything in the application's Composition Root:

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

You can use a DI Container to compose at this level, but you don't have to. No factories are involved.

Entertainer answered 24/1, 2012 at 7:29 Comment(2)
thanks for the answer. a question about the composition root. What should be the composition root when it comes to an EJB call or a web service? Is it the called method itself?Selaginella
Those are Java specifics with which I'm not familiar, but as a general concept composition happens very late: when you can't possibly postpone it any longer.Entertainer
P
2

If you inject too many factories that is a code smell called constructor over-injection that indicates your class is doing too much.

Many containers provide a feature called auto-factories. That means they generate factories of type Func<T>automatically if they know how to generate T.

Castle Windsor has an advanced feature called Typed Factory facilities which generates implementations of a factory interface on-the-fly.

There is also a port of typed factories for Unity in the TecX project.

Pileus answered 24/1, 2012 at 7:8 Comment(0)
B
0

If you end up using Unity, I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.

The usage is the following:

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

You just have to create the IFooFactory interface with a method returning IFoo, and the rest is done for you by the library. You can resolve IFooFactory and use it to create IFoo objects straight away.

Bicephalous answered 6/12, 2012 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.