加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 04:04:52 所属栏目:百科 来源:网络整理
导读:我正在使用Unity IoC容器,我需要拦截对某个基本界面的Resolve的任何调用,并运行我自己的自定义代码来构造这些类型. 换句话说,在下面的示例代码中,当我调用container.Resolve IFooN()时,如果没有具体实现类型的实例,它调用MyFactoryFunction构造一个,否则我希
我正在使用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;
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读