我正在使用Unity IoC容器,我需要拦截对某个基本界面的Resolve的任何调用,并运行我自己的自定义代码来构造这些类型.
换句话说,在下面的示例代码中,当我调用container.Resolve< IFooN>()时,如果没有具体实现类型的实例,它调用MyFactoryFunction构造一个,否则我希望它返回缓存副本.
标准的Unity容器不能构造这些对象(更新:因为它们是.NET远程处理对象,所以具体的类不存在于本地计算机上的任何程序集中),我不想在前面创建它们用RegisterInstance存储它们.
interface IFoo : IBase { ... } interface IFoo2 : IBase { ... } ... container.Resolve<IFoo2>(); ... IBase MyFactoryFunction(Type t) { ... }
解决方法
为了完整,我应该添加另一个在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 举报,一经查实,本站将立刻删除。