How to create objects using a static factory method?

burnt1ce picture burnt1ce · Sep 28, 2011 · Viewed 23.5k times · Source

I know Unity can be configured to use a class' constructor to create an instance of a class (like below) but that's not what I want.

container.RegisterType<IAuthoringRepository, AuthoringRepository>();

I would like to configure Unity to use a factory method with the windows identity passed as a parameter (ie: RepositoryFactory.CreateAuthoringRepository(WindowsIdentity.GetCurrent())) when resolving a type of IAuthoringRepository. How do i do this?

Answer

TrueWill picture TrueWill · Sep 28, 2011

One way is to have RepositoryFactory implement IRepositoryFactory, then register that. Resolved types can get a factory, then call its CreateAuthoringRepository method. You could create an overload called CreateAuthoringRepositoryForCurrentIdentity if desired, or register an IIdentity dependency of the factory with Unity.

I'd probably just inject a factory and leave the CreateAuthoringRepository method as you have it, then have the clients pass WindowsIdentity.GetCurrent(). That way the identity is always fresh, and you can mock the factory for testing.

Alternately, you can specify a delegate with InjectionFactory:

void Main()
{
    using (var container = new UnityContainer())
    {
        container.RegisterType<IAuthoringRepository>(
            new InjectionFactory(c => CreateAuthoringRepository()));

        Console.WriteLine("debug - resolving model");
        var model = container.Resolve<Model>();
    }
}

public IAuthoringRepository CreateAuthoringRepository()
{
    Console.WriteLine("debug - calling factory");
    return new AuthoringRepository
        { Identity = WindowsIdentity.GetCurrent() };
}

public class Model
{
    public Model(IAuthoringRepository repository)
    {
        Console.WriteLine(
            "Constructing model with repository identity of "
            + repository.Identity);
    }
}

public interface IAuthoringRepository
{
    IIdentity Identity { get; }
}

public class AuthoringRepository : IAuthoringRepository
{
    public IIdentity Identity { get; set; }
}

This prints:

debug - resolving model
debug - calling factory
Constructing model with repository identity of System.Security.Principal.WindowsIdentity

That's for Unity 2.0. With earlier versions, see StaticFactoryExtension.