2010-06-17 93 views
7

我試圖同時仍然使用Unity容器實現自己的攔截。我想以尊重終身管理者的方式來做到這一點。即如果它是一個PerResolveLifetimeManager,那麼我想要包裝這個實例一次,並且我希望在整個解析過程中使用這個包裝的實例。統一容器:使用PerResolveLifetimeManager和自定義攔截

到目前爲止,我實現了一個使用自定義的UnityContainerExtension類添加到我的容器中的BuilderStrategy(我將PostInitialization傳遞給AddNew方法;我不確定最合適的值是什麼,但這似乎工作)。在我的BuilderStrategy中的一個PostBuildUp覆蓋中,我用我的包裝值替換context.Existing。

當我用這個用一生PerResolve,出現一個包,但只有在第一次使用的依賴得到包裹實例,其餘獲得非包裹實例。即如果我的ctor接受IFoo foo1和IFoo foo2,則只有foo1是我的包裝實例,而foo2是展開的實例。

下面是一個簡單的攝製(爲簡單起見,我使用的,而不是包裝另一個階級和Foo2的一個實例):

public class MyInterception : UnityContainerExtension 
{ 
    protected override void Initialize() 
    { 
     Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.PostInitialization); 
    } 
} 

public class MyInterceptionStrategy : BuilderStrategy 
{ 
    public override void PostBuildUp(IBuilderContext context) 
    { 
     if (!context.OriginalBuildKey.Type.IsInterface) 
     { 
      return; 
     } 

     context.Existing = new Foo2(); 
    } 
} 

public class Bar 
{ 
    public Bar(IFoo f1, IFoo f2, IFoo f3) 
    { 
    } 
} 

public interface IFoo 
{ 
} 

public class Foo1 : IFoo 
{ 
} 

public class Foo2 : IFoo 
{ 
} 

public void Main() 
{ 
    UnityContainer container = new UnityContainer(); 
    container.AddNewExtension<MyInterception>(); 
    container.RegisterType(typeof (IFoo), typeof (Foo1), new PerResolveLifetimeManager()); 

    container.Resolve<Bar>(); 
} 

如果你把一個斷點PostBuildUp和酒吧的構造器和調試主通過Bar的解析,你可以看到PostBuildUp只被調用一次。然而,在酒吧的構造,F1是foo2的實例(一個「包裝」的實例)whileas F2和F3是Foo1(展開)的實例。

我在想,如果我想是可能的,如果我採取正確的方法呢?我的問題與我添加BuilderStrategy的生命週期和/或UnityBuildStage有關嗎?

謝謝

+0

你的意思是Unity Game Engine? – 2010-11-10 00:29:47

+4

我相信他是指在容器http://unity.codeplex.com/中的Unity。 – aqwert 2010-11-10 02:07:47

回答

2

你在構建策略中做得太遲了。不幸的是,在這個時候我沒有爲更詳細的原因代碼行爲的ObjectBuilder的組件內這種方式。

希望,我將返回當我有更多的時間來分析統一ObjectBuilder的,但解決您的問題在此期間,剛剛從PostInitialization更改UnityBuildStage枚舉值設置TypeMapping

Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup); 

我全碼:

using System; 
using Microsoft.Practices.ObjectBuilder2; 
using Microsoft.Practices.Unity; 
using Microsoft.Practices.Unity.ObjectBuilder; 

namespace UnityInterceptors 
{ 
    class Program 
    { 
     public class MyInterception : UnityContainerExtension 
     { 
      protected override void Initialize() 
      { 
       Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup); 
      } 
     } 
     public class MyInterceptionStrategy : BuilderStrategy 
     { 
      public override void PostBuildUp(IBuilderContext context) 
      { 
       if (!context.OriginalBuildKey.Type.IsInterface) 
       { 
        return; 
       } 

       context.Existing = new Foo2(); 
      } 
     } 

     public class Bar 
     { 
      public Bar(IFoo f1, IFoo f2, IFoo f3) 
      { 
       Console.WriteLine(f1.GetType().Name); 
       Console.WriteLine(f2.GetType().Name); 
       Console.WriteLine(f3.GetType().Name); 
      } 
     } 

     public interface IFoo 
     { 
     } 

     public class Foo1 : IFoo 
     { 
     } 

     public class Foo2 : IFoo 
     { 
     } 

     public static void Main() 
     { 
      UnityContainer container = new UnityContainer(); 
      container.AddNewExtension<MyInterception>(); 
      container.RegisterType(typeof(IFoo), typeof(Foo1), new PerResolveLifetimeManager()); 

      container.Resolve<Bar>(); 

      Console.ReadLine(); 
     } 
    } 
} 
  • 另外請注意,我使用Unity 2.0庫。可能是已解決的某種類型的錯誤。
相關問題