I am using the Unity IoC container, and I need to intercept any calls to Resolve for a certain base interface, and run my own custom code to construct those types.
Update This answer was for Unity 1.2. For a solution that works with Unity 2, see my other answer.
OK, I have implemented the extension myself. In the builder I cache the object as I want it to be a singleton w.r.t my container. The reason for baseContext is that I want it to be cached in the top level container rather than in any child containers from which it was requested.
public class FactoryMethodUnityExtension : UnityContainerExtension
{
private Func factory;
public FactoryMethodUnityExtension(Func factory)
{
this.factory = factory;
}
protected override void Initialize()
{
var strategy = new CustomFactoryBuildStrategy(factory, this.Context);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
}
public class CustomFactoryBuildStrategy : BuilderStrategy
{
private Func factory;
private ExtensionContext baseContext;
public CustomFactoryBuildStrategy(Func factory, ExtensionContext baseContext)
{
this.factory = factory;
this.baseContext = baseContext;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = (NamedTypeBuildKey)context.OriginalBuildKey;
if (key.Type.IsInterface && typeof(T).IsAssignableFrom(key.Type))
{
object existing = baseContext.Locator.Get(key.Type);
if (existing == null)
{
// create it
context.Existing = factory(key.Type);
// cache it
baseContext.Locator.Add(key.Type, context.Existing);
}
else
{
context.Existing = existing;
}
}
}
}
Adding the extension is quite simple:
MyFactory factory = new MyFactory();
container = new UnityContainer();
container.AddExtension(new FactoryMethodUnityExtension(factory.Create));