2016-04-23 41 views
0

似乎找不到任何有用的指南,了解如何在从StructureMap 2升级到版本3时重新生成当前由代码库中的TypeInterceptor提供的功能(无法升级到v4,因为我们不是' t使用.NET 4.6)。TypeInterceptor替换Structuremap 3

本质上讲拦截确实是这样的:

public class TheInterceptor : TypeInterceptor 
{ 
    private Dictionary<string, string> typesToIntercept; 

    public TheInterceptor(IDictionary<string, string> typesToIntercept) 
    { 
     // Passed in on ctor, comes from XML configuration section. 
     this.typesToIntercept = typesToIntercept; 
    } 

    public object Process(object target, StructureMap.IContext ctx) 
    { 
     var typedTarget = target as BaseType; 
     var key = target.GetType().FullName; 

     if (typedTarget == null || !typesToIntercept.ContainsKey(key)) 
     { 
      return target; 
     } 

     var propertyOverrideType = typesToIntercept[key]; 

     typedTarget.BaseProperty = ctx.GetInstance<IBaseInterface>(propertyOverrideType); 

     return typedTarget; 
    } 
} 

所以我们基本上保持一个字典,其中的关键是我们要拦截的类型和价值是实现已知接口特定类型,我们想要设置被拦截对象的属性。

FWIW我没有写出原始代码,我只是无法弄清楚在StructureMap 3中镜像这种行为的正确方法是什么。我觉得这可以在没有拦截器的情况下完成,但我相信它是这样实现的,以便这种行为可以跨多个站点使用(它在共享库中),而不必每个站点都明确地处理拦截行为,所以如果可能的话,我想保留这种用法。

回答

1

所以我最终通过反复试验了解了这一点。你需要的是一个ActivatorInterceptor,并使用Action委托来执行之前在TypeInterceptor的Process方法内部执行的逻辑。所以从我上面的代码片段,它变成:

public class InterceptorPolicy : IInterceptorPolicy 
{ 
    private readonly IDictionary<string, string> typesToIntercept; 

    public InterceptorPolicy(IDictionary<string, string> types) 
    { 
     this.typesToIntercept = types; 
    } 

    public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance) 
    { 
     if (instance.ReturnedType.IsSubclassOf(typeof(BaseType))) 
     { 
      yield return new ActivatorInterceptor<BaseType>((ctx, x) => this.Activate(ctx, x)); 
     } 
    } 

    private void Activate(IContext ctx, BaseType instance) 
    { 
     var key = instance.GetType().FullName; 

     if (this.typesToIntercept.ContainsKey(key)) 
     { 
      var propertyOverrideType = this.typesToIntercept[key]; 

      instance.BaseProperty = ctx.GetInstance<IBaseInterface>(propertyOverrideType); 
     } 
    } 
}