Wednesday, June 18, 2008

Configuring and Supplying a Factory with Unity

Here is a code-sample which allows the Factory to be Container-dependent, and thus configurable in the container setup code. Notice that I registered the unity instance with itself. If you do not do this, when the Factory is created, Unity will see that a UnityContainer is needed by the constructor and instantiate a new UnityContainer, which will not have the correct configuration. If you have registered the configured unity instance, then it will be supplied to the Factory. Also note that the unity configuration can be changed by other parts of the application, so if you want to avoid that, you might want to make a copy of the container inside the Factory constructor.

using System;
using Microsoft.Practices.Unity;
namespace DI
{
#region Container-independent

public interface I { }
public interface IFactory<T>
{
T Create();
}

public class A : I
{
}
public class Aprime : I
{
}
public class B
{
IFactory<I> Ifactory;

public B(IFactory<I> f) { Ifactory = f; }

public void SomeMethod()
{
I a = Ifactory.Create();
Console.WriteLine(a.ToString());
}
}

#endregion
//--------------------------------------------------------------------------------
#region Unity container Dependent

public class Factory<T> : IFactory<T> where T : class
{
UnityContainer container;
public Factory(UnityContainer unity) { this.container = unity; }
public T Create() { return container.Resolve<T>(); }
}
class Program
{
static void Main(string[] args)
{
UnityContainer unity = new UnityContainer();

// register the Unity container so that this instance is provided to factory
unity.RegisterInstance(unity);

// tell Unity to provide A when asked for interface I
unity.RegisterType<I, A>();

// use the Unity enabled factory
unity.RegisterType(typeof(IFactory<I>), typeof(Factory<I>));

B b = unity.Resolve<B>();
b.SomeMethod();

// now tell Unity to provide Aprime when asked for I
unity.RegisterType<I, Aprime>();
b.SomeMethod();

}
}
#endregion
}

See: http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=29697 for a discussion about this.

2 comments:

MM said...

this is a nice solution for a problem i've been thinking about. thanks for posting it.

Anonymous said...
This comment has been removed by a blog administrator.