2010-06-17 94 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库。可能是已解决的某种类型的错误。
相关问题