2017-03-13 42 views
0

當我在Castle Windsor中使用攔截器時,只要調用函數(IInvocation類型的調用參數),就可以訪問調用目標。Castle Windsor攔截器 - 獲得目標已經在ctor

是否有可能得到攔截的目標已經在這個攔截器的構造函數,這樣我可以像如下編寫代碼:

public class MyInterceptor: IInterceptor 
{ 
    public MyInterceptor(ITargetOfInterception target, ILogger logger) 
    { 
     logger.Log("Interceptor created for target type: " + target.GetType()); 
    } 
} 

回答

1

這是不可能獲得訪問目標的構造函數,但你可以實現你通過實現IOnBehalfAwaresee doco here)之後是什麼

public void SetInterceptedComponentModel(ComponentModel target) 
{ 
    logger.Log("Interceptor created for target: " + target.ToString()); 
} 
+0

非常感謝,正是我一直在尋找的。是否也可以在這個地方獲得對InvocationTarget的引用? (與Intercept-method中的IInvocation.InvocationTarget相同?)。我無法在ComponentModel中找到等效屬性。 – user2959547

0

你應該有你的實例已經...

container.Register(Component.For<IInterceptor>().ImplementedBy<Logger>().Named("myinterceptor")); 

然後,你將用攔截器的屬性裝飾每個類。

[Interceptor("myinterceptor")] 
public class Logger : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) { 
     Console.WriteLine(">> type in <<"); 
     invocation.Proceed(); 
     Console.WriteLine(">> type out <<"); 
    }  
} 

如果實施攔截,你就能知道哪種類型的,因爲你已經定義了這樣的橫切關注點由攔截器來解決解決。

我想你想讓你的攔截器知道所有需要攔截器的合約,而不是所有類型的攔截器的指令。我希望這有幫助!!

編輯:這是我如何使用統一到記錄儀:

Public Class LoggingInterceptionBehavior 
     Implements IInterceptionBehavior 
     Public Function Invoke(input As IMethodInvocation, getNext As GetNextInterceptionBehaviorDelegate) As IMethodReturn Implements IInterceptionBehavior.Invoke 
      ' Before invoking the method on the original target. 
      Dim icp As ClaimsPrincipal = TryCast(Thread.CurrentPrincipal, ClaimsPrincipal) 

      ' Access IClaimsIdentity which contains claims 
      Dim claimsIdentity As ClaimsIdentity = DirectCast(icp.Identity, ClaimsIdentity) 
      Dim param = GetParam(input) 

      If claimsIdentity IsNot Nothing Then 
       If param IsNot Nothing Then 
        WriteLog([String].Format("{0} is invoking method {1} at {2} with a parameter of {3}", claimsIdentity.Name, input.MethodBase, DateTime.Now.ToLongTimeString(), param)) 
       Else 
        WriteLog([String].Format("{0} is invoking method {1} at {2} without a parameter", claimsIdentity.Name, input.MethodBase, DateTime.Now.ToLongTimeString())) 
       End If 

      Else 
       'no claim 
       WriteLog([String].Format("NO CLAIM Invoking method {0} at {1} with a parameter of {2}", input.MethodBase, DateTime.Now.ToLongTimeString(), param)) 
      End If 

      ' Invoke the next behavior in the chain. 
      Dim result = getNext()(input, getNext) 

      ' After invoking the method on the original target. 
      If result.Exception IsNot Nothing Then 
       WriteCriticalLog([String].Format("Method {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString())) 
      Else 
       WriteLog([String].Format("Method {0} returned {1} at {2}", input.MethodBase, result.ReturnValue, DateTime.Now.ToLongTimeString())) 
      End If 

      Return result 
     End Function 

End Class 

我如何註冊他們:

container.RegisterType(Of IXXXService, XXXService)(New Interceptor(Of InterfaceInterceptor)(), 
                   New InterceptionBehavior(Of LoggingInterceptionBehavior)) 
+0

謝謝你的評論。我有一個攔截器的實現(例如日誌攔截器),以攔截不同種類的類。我想檢測,如果這樣的類已解決並記錄下來。而不是第一次調用第一個方法時。 – user2959547

+0

2個答案。 1:我建議移動到Unity來獲得這些功能。要做到這一點需要一點學習曲線才能做到這一點。 2:文檔有點稀疏 - https://github.com/castleproject/Windsor/blob/master/docs/debugger-views.md,但它應該引導你如何調試你的容器。 – Programmer

+0

1.走向統一不是我的選擇,我非常喜歡Castle Windsor ;-)。 2:我不想調試我的容器。我只想使用攔截器並在構造函數中獲得對調用目標的訪問(與爲攔截方法實現的方法相同)。 – user2959547

0

雖然我不知道你爲什麼需要它,我能想到的2種可能解決方案。

首先,您可以掛接container.ComponentRegistered事件(or some other event of your choosing),並檢查處理程序以查看攔截器。其次,你可以在攔截器中使用一些靜態散列表,並記錄在攔截上檢測到「新」目標的時間。

也許第一個解決方案就是你想要的。

相關問題