Factory Factory pattern: easier than using a container

Here’s a simple example of a class that creates file transfers using different protocols, which can be combined into a big queue later:

public class TransferFactory : ITransferFactory
{
    public Transfer CreateFtpTransfer(string path)
    {
        return new Transfer(path, ftpStreamFactory);
    }
    
    public Transfer CreateHttpTransfer(string path)
    {
        return new Transfer(path, httpStreamFactory);
    }

    public Transfer CreateSmbTransfer(string path)
    {
        return new Transfer(path, smbStreamFactory);
    }

    public Transfer CreateSftpTransfer(string path)
    {
        return new Transfer(path, sftpStreamFactory);
    }
}

It’s based loosely on something I wrote last week at work, and you can see some pretty classic examples of the Strategy and Abstract Factory patterns here. But where do all the stream factories come from? You could inject them all separately:

public class TransferFactory : ITransferFactory
{
    public TransferFactory(IStreamFactory ftpStreamFactory,
        IStreamFactory httpStreamFactory,
        IStreamFactory smbStreamFactory,
        IStreamFactory sftpStreamFactory)
    {
        this.ftpStreamFactory = ftpStreamFactory;
        this.httpStreamFactory = httpStreamFactory;
        this.smbStreamFactory = smbStreamFactory;
        this.sftpStreamFactory = sftpStreamFactory;
    }

    ...
}

But classes like this are horrible to register in an IoC container. Named instances, kilometers of identical positional parameters, and nothing preventing you putting them in the wrong order by accident… messy.

A tidier approach would be to employ the factory factory pattern, where instead of injecting all the factories separately, you just provide one that can create them all:

public class TransferFactory : ITransferFactory
{
    public TransferFactory(IStreamFactoryFactory streamFactories)
    {
        this.streamFactories = streamFactories;
    }

    public Transfer CreateFtpTransfer(string path)
    {
        return new Transfer(path, streamFactories.CreateFtpStreamFactory());
    }
    
    public Transfer CreateHttpTransfer(string path)
    {
        return new Transfer(path, streamFactories.CreateHttpStreamFactory());
    }

    ...
}

Now some would argue that having factories to create factories is a sure sign of being an architect astronaut, and noone should ever need such a thing. But in examples like this I think they are entirely appropriate, and make your code that much easier to work with.

March 17, 2010

5 Comments

Thom Lawrence on March 17, 2010 at 11:37 pm.

Why not just pass concrete classes in the constructor?

Richard on March 18, 2010 at 10:04 am.

Thom : how do you know what the concrete types will be?

Chris Canal on March 18, 2010 at 1:04 pm.

We use convention based resolution with Castle Windsor for things like this. We resolve dependencies based on the constructor parameter name that matches the implementations registered key.

Mike on March 31, 2010 at 1:56 pm.

You can use ServiceLocation- like Microsoft’s ServiceLocator functionality in the EntLib. You ask a third-party (the service locator) for the concrete class based on your interface. Same principle as the Factory-of-Factories, without the need for constructor injection.

Thom Lawrence on May 15, 2010 at 12:54 am.

Even if for some odd reason you have multiple FtpStreamFactories, they should all derive from something more specific than IStreamFactory. There is no reason to be passing four IStreamFactories into that constructor – pass more specific types and the problem goes away entirely. As does this FactoryFactory monstrosity. :P

Leave a Reply