gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:01:40 26 4
gpt4 key购买 nike

我正在使用 Unity IoC 容器,我需要拦截对特定基础接口(interface)的任何 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;
}
}
}

关于c# - Unity 的自定义对象工厂扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1380375/

26 4 0
文章推荐: c# - 是否可以将 Protobuf-Net 与没有无参数构造函数的类一起使用?
文章推荐: java - 安卓电子邮件验证
文章推荐: android - 运行线程类方法中的 sendBroadcast 编译错误,Android
文章推荐: c# - 当 T 未知时,如何使用反射执行 List.Cast