Unity的自定义对象工厂扩展定义代码构造这些类型。换句话说,在下面的示例代码中,当我调用container.Resolve()时,如果它没有具体实现类型的实例,我调用MyFactoryFunction来构造一个,否则我希望它返回一个缓存的副本。这些对象不能由标准的Unity容器构造(更新:因为它们是.NET远程对象,本地机器上的任何程序集中都不存在具体类),我不想使用RegisterInstance预先创建它们存储它们。接口IFoo:IBase{...}接口IFoo2:IBase{...}...container.Resolve();...IBaseMyFactoryFunction(Typet){...}我假设我可以创建一个Unity扩展来执行此操作,但我想知道是否已经有我可以借用的解决方案。为了完整起见,我应该添加另一个在Unity2下有效的答案,因为我的另一个答案不再适用。由于您需要制定自定义构建器策略,因此要多一些。感谢Unity项目中的ctavares,他们在现实这个方面为这个线程提供了很多帮助:publicclassFactoryUnityExtension:UnityContainerExtension{privateICustomFactoryfactory;私有CustomFactoryBuildStrategy策略;publicFactoryUnityExtension(ICustomFactoryfactory){this.factory=factory;}protectedoverridevoidInitialize(){this.strategy=newCustomFactoryBuildStrategy(factory,Context);上下文.Strategies.Add(策略,UnityBuildStage.PreCreation);Context.Policies.Set(newParentMarkerPolicy(Context.Lifetime),newNamedTypeBuildKey());}}publicclassParentMarkerPolicy:IBuilderPolicy{privateILifetimeContainerlifetime;publicParentMarkerPolicy(ILifetimeContainerlifetime){this.lifetime=lifetime;}publicvoidAddToLifetime(objecto){lifetime.Add(o);}}publicinterfaceICustomFactory{objectCreate(Typet);布尔CanCreate(类型t);}publicclassCustomFactoryBuildStrategy:BuilderStrategy{privateExtensionContextbaseContext;私有ICustomFacto工厂;publicCustomFactoryBuildStrategy(ICustomFactoryfactory,ExtensionContextbaseContext){this.factory=factory;this.baseContext=baseContext;}publicoverridevoidPreBuildUp(IBuilderContextcontext){varkey=(NamedTypeBuildKey)context.OriginalBuildKey;if(factory.CanCreate(key.Type)&&context.Existing==null){context.Existing=factory.Create(key.Type);varltm=newContainerControlledLifetimeManager();ltm.SetValue(context.Existing);//找到容器将此添加到IPolicyListparentPolicies;varparentMarker=context.Policies.Get(newNamedTypeBuildKey(),outparentPolicies);//TODO:添加错误检查-如果缺少策略,则扩展配置错误//将生命周期管理器添加到容器parentPolicies.Set(ltm,newNamedTypeBuildKey(key.Type));//并添加到LifetimeContainer以便处理它parentMarker.AddToLifetime(ltm);//短路链的其余部分,对象已经创建context.BuildComp莱特=真;}}}UPDATEThisanswerworksforUnity1.2SeemyotheranswerforasolutionthatworksforUnity2.好的,我自己实现了扩展。在构建器中,我缓存了对象,因为我希望它成为一个单独的容器。baseContext的原因是我希望它缓存在顶级容器中,而不是在任何请求它的子容器中。公共类FactoryMethodUnityExtension:UnityContainerExtension{privateFuncfactory;publicFactoryMethodUnityExtension(Funcfactory){this.factory=factory;}protectedoverridevoidInitialize(){varstrategy=newCustomFactoryBuildStrategy(factory,this.Context);上下文.Strategies.Add(策略,UnityBuildStage.PreCreation);}}publicclassCustomFactoryBuildStrategy:BuilderStrategy{privateFunc工厂;私有ExtensionContextbaseContext;publicCustomFactoryBuildStrategy(Funcfactory,ExtensionContextbaseContext){this.factory=factory;this.baseContext=baseContext;}publicoverridevoidPreBuildUp(IBuilderContextcontext){varkey=(NamedTypeBuildKey)context.OriginalBuildKey;如果(key.Type.IsInterface&&typeof(T).IsAssignableFrom(key.Type)){objectexisting=baseContext.Locator.Get(key.Type);if(existing==null){//创建它context.Existing=factory(key.Type);//缓存它baseContext.Locator.Add(key.类型,上下文。现有的);}else{context.Existing=existing;添加扩展很容易:MyFactoryfactory=newMyFactory();container=newUnityContainer();container.AddExtension(newFactoryMethodUnityExtension(factory.Create));Unity(v2)允许您指定允许多种不同功能的工厂,包括采用类型来构建/命名等。简单示例:UnityContainercont=newUnityContainer();有一个简单的创建测试方法——但这可以扩展到您想要的任何工厂。这将绕过正常的创建过程(为了简洁)并调用最长的构造函数,所有后续行为,包括属性设置,仍将执行。cont.RegisterType(newInjectionFactory(c=>CreateTest()));varsvc=cont.Resolve();Unity容器已经作为一个知道如何构造(并执行依赖注入)任何类型的工厂,因此接受类型t的工厂看起来是多余的。你能详细说明为什么这是不可能的吗?如果那真的不可能(很可能工作量太大),那么也许您可以在容器中注册您的工厂?以上就是C#学习教程:Unity的自定义对象工厂扩展分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
