更新此答案适用于 Unity 1.2。有关适用于 Unity 2 的解决方案,请参阅我的其他答案。
好的,我自己实现了扩展。在构建器中,我缓存对象,因为我希望它成为我的容器中的单例。原因baseContext
是我希望它被缓存在顶级容器中,而不是在请求它的任何子容器中。
public class FactoryMethodUnityExtension<T> : UnityContainerExtension
{
private Func<Type,T> factory;
public FactoryMethodUnityExtension(Func<Type,T> factory)
{
this.factory = factory;
}
protected override void Initialize()
{
var strategy = new CustomFactoryBuildStrategy<T>(factory, this.Context);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
}
public class CustomFactoryBuildStrategy<T> : BuilderStrategy
{
private Func<Type,T> factory;
private ExtensionContext baseContext;
public CustomFactoryBuildStrategy(Func<Type,T> 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;
}
}
}
}
添加扩展非常简单:
MyFactory factory = new MyFactory();
container = new UnityContainer();
container.AddExtension(new FactoryMethodUnityExtension<IBase>(factory.Create));