微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Unity的自定义对象工厂扩展

我正在使用Unity IoC容器,我需要拦截对某个基本界面的Resolve的任何调用,并运行我自己的自定义代码来构造这些类型.

换句话说,在下面的示例代码中,当我调用container.Resolve< IFooN>()时,如果没有具体实现类型的实例,它调用MyFactoryFunction构造一个,否则我希望它返回缓存副本.

标准的Unity容器不能构造这些对象(更新:因为它们是.NET远程处理对象,所以具体的类不存在于本地计算机上的任何程序集中),我不想在前面创建它们用RegisterInstance存储它们.

interface IFoo : IBase { ... }
interface IFoo2 : IBase { ... }

...
container.Resolve<IFoo2>();

...
IBase MyFactoryFunction(Type t)
{
    ...
}

我假设我可以创建一个Unity扩展来做到这一点,但我想知道是否已经有一个可以借用的解决方案.

解决方法

为了完整,我应该添加一个在Unity 2下工作的答案,因为我的其他答案不再有效.由于您需要制定自定义构建器策略,因此它的参与程度有所增加.感谢Unity项目的ctavares,他为 this thread提供了大量的帮助:
public class FactoryUnityExtension : UnityContainerExtension
{
    private ICustomFactory factory;
    private CustomFactoryBuildStrategy strategy;

    public FactoryUnityExtension(ICustomFactory factory)
    {
        this.factory = factory;
    }

    protected override void Initialize()
    {
        this.strategy = new CustomFactoryBuildStrategy(factory,Context);
        Context.Strategies.Add(strategy,UnityBuildStage.PreCreation);
        Context.Policies.Set<ParentMarkerPolicy>(new ParentMarkerPolicy(Context.Lifetime),new NamedTypeBuildKey<ParentMarkerPolicy>());
    }
}

public class ParentMarkerPolicy : IBuilderPolicy
{
    private ILifetimeContainer lifetime;

    public ParentMarkerPolicy(ILifetimeContainer lifetime)
    {
        this.lifetime = lifetime;
    }

    public void AddToLifetime(object o)
    {
        lifetime.Add(o);
    }
}

public interface ICustomFactory
{
    object Create(Type t);
    bool CanCreate(Type t);
}

public class CustomFactoryBuildStrategy : BuilderStrategy
{
    private ExtensionContext baseContext;
    private ICustomFactory factory;


    public CustomFactoryBuildStrategy(ICustomFactory factory,ExtensionContext baseContext)
    {
        this.factory = factory;
        this.baseContext = baseContext;
    }

    public override void PreBuildUp(IBuilderContext context)
    {
        var key = (NamedTypeBuildKey)context.OriginalBuildKey;

        if (factory.CanCreate(key.Type) && context.Existing == null)
        {
            context.Existing = factory.Create(key.Type);
            var ltm = new ContainerControlledLifetimeManager();
            ltm.SetValue(context.Existing);

            // Find the container to add this to
            IPolicyList parentPolicies;
            var parentMarker = context.Policies.Get<ParentMarkerPolicy>(new NamedTypeBuildKey<ParentMarkerPolicy>(),out parentPolicies);

            // Todo: add error check - if policy is missing,extension is misconfigured

            // Add lifetime manager to container
            parentPolicies.Set<ILifetimePolicy>(ltm,new NamedTypeBuildKey(key.Type));
            // And add to LifetimeContainer so it gets disposed
            parentMarker.AddToLifetime(ltm);

            // Short circuit the rest of the chain,object's already created
            context.BuildComplete = true;
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐