Custom object factory extension for Unity

后端 未结 4 1283
你的背包
你的背包 2021-01-02 06:05

I am using the Unity IoC container, and I need to intercept any calls to Resolve for a certain base interface, and run my own custom code to construct those types.

4条回答
  •  甜味超标
    2021-01-02 06:33

    Update This answer was for Unity 1.2. For a solution that works with Unity 2, see my other answer.


    OK, I have implemented the extension myself. In the builder I cache the object as I want it to be a singleton w.r.t my container. The reason for baseContext is that I want it to be cached in the top level container rather than in any child containers from which it was requested.

     public class FactoryMethodUnityExtension : UnityContainerExtension
     {
         private Func factory; 
    
         public FactoryMethodUnityExtension(Func factory)
         {
             this.factory = factory;
         }
    
         protected override void Initialize()
         {
             var strategy = new CustomFactoryBuildStrategy(factory, this.Context);
             Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);             
         }
     } 
    
     public class CustomFactoryBuildStrategy : BuilderStrategy
     {
         private Func factory;
         private ExtensionContext baseContext;
    
         public CustomFactoryBuildStrategy(Func factory, ExtensionContext baseContext)
         {
            this.factory = factory;
            this.baseContext = baseContext;
         }
    
         public override void PreBuildUp(IBuilderContext context)
         {
             var key = (NamedTypeBuildKey)context.OriginalBuildKey;
    
             if (key.Type.IsInterface && typeof(T).IsAssignableFrom(key.Type))
             {
                 object existing = baseContext.Locator.Get(key.Type);
                 if (existing == null)
                 {
                     // create it
                     context.Existing = factory(key.Type);
                     // cache it
                     baseContext.Locator.Add(key.Type, context.Existing);
                 }
                 else
                 {
                     context.Existing = existing;
                 }
             }
         }
     }
    

    Adding the extension is quite simple:

    MyFactory factory = new MyFactory();
    container = new UnityContainer();
    container.AddExtension(new FactoryMethodUnityExtension(factory.Create));
    

提交回复
热议问题