2016-04-23 40 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); 
     } 
    } 
}