2012-01-06 55 views
1

在我的WCF Web應用程序中,我配置了用於截取的Unity容器。以下是我的統一配置。使用Unity 2.0截取的WCF服務不可攔截

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/> 

    <assembly name="Infrastructure" /> 
    <assembly name="WCFServiceLib1"/> 

    <namespace name="Infrastructure"/> 
    <namespace name="WCFServiceLib1" /> 

    <container> 
     <extension type="Interception" /> 
     <register type="IService1" mapTo="Service1"> 
     <interceptor type="InterfaceInterceptor"/> 
     <interceptionBehavior type="LogPerformanceDataBehavior"/> 
     </register> 
    </container> 
</unity> 

當我嘗試使用wcftestclient工具調用服務上的方法時,會引發以下異常。

ArgumentException - 類型WCFServiceLib1.Service1不可攔截。
參數名:interceptedType

我用svctraceviewer工具來獲得上述異常的詳細信息。

以下是類LogPerformanceDataBehavior

public class LogPerformanceDataBehavior : IInterceptionBehavior 
{ 
    public IEnumerable<Type> GetRequiredInterfaces() 
    { 
     return Type.EmptyTypes; 
    } 

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) 
    { 
     var watch = new Stopwatch(); 

     watch.Start(); 
     IMethodReturn methodReturn = getNext()(input, getNext); 
     watch.Stop(); 

     string sb = string.Format("Method {0}.{1} executed in: ({2} ms, {3} ticks){4}", 
            input.MethodBase.DeclaringType.Name, input.MethodBase.Name, 
            watch.ElapsedMilliseconds, watch.ElapsedTicks, Environment.NewLine); 

     using (StreamWriter outfile = new StreamWriter(@"c:\logs\Performance.txt")) 
     { 
      outfile.Write(sb); 
     } 

     return methodReturn; 
    } 

    public bool WillExecute 
    { 
     get { return true; } 
    } 
} 


什麼可能是錯誤的執行?

+0

你試圖攔截您_service_或_client側proxy_? WCF有自己的基礎設施來攔截對服務的呼叫。我認爲這不適用於任何其他攔截機制(無論是Unity還是其他)。如果你想監視WCF的性能,你應該看看[WCF性能計數器](http://msdn.microsoft.com/en-us/library/ms735098.aspx) – 2012-01-06 11:38:35

+0

@SebastianWeber我想攔截調用服務上的任何方法。我已使用此[鏈接]中的步驟(http://geekswithblogs.net/13DaysaWeek/archive/2010/12/01/dependency-injection-and-wcf-services.aspx)爲服務配置統一。 – surajnaik 2012-01-06 11:48:48

+0

我知道UnityServiceHost/Factory/InstanceProvider,但我不確定在這個場景中使用Unity的攔截機制是一個好主意(或者甚至可能).WCF有一個呼叫處理程序的管道,它從挑選服務的呼叫開始如果你只是對性能測量感興趣,我會堅持使用WCF內置的性能指標計數器。它們經過驗證,速度和記錄良好。如果你想使用攔截器對於別的東西:看看WCF基礎設施爲您提供了什麼。它爲可擴展性而構建。 – 2012-01-06 13:08:57

回答

6

問題是WCF實例提供程序未解析接口。它解決了服務類型。你正在使用一個接口攔截器,它不能直接應用於類。請參閱Comparison of Interception Techniques

修復的方法是:

  1. 更改爲VirtualMethodInterceptor
  2. 標記任何要攔截的服務方法爲virtual

示例註冊:

<register type="Service1" >   
    <interceptor type="VirtualMethodInterceptor"/> 
    <interceptionBehavior type="LogPerformanceDataBehavior"/>  
</register> 
+0

或者您可以從MarshalByRefObject繼承並使用TransparentProxyInterceptor或修改WCF實例提供程序以通過接口進行解析。 – 2012-01-10 06:09:21

+0

感謝您的輸入@Tuzo – surajnaik 2012-01-10 07:15:18

+0

如果您只是在做一個IInstanceProvider,那麼嘗試解析一個接口不起作用。我嘗試過這個。 WCF想要一個類實例,如果你給它任何東西,它將開始拋出異常。 從技術上講,MarshalByRefObject是一個選項,但是這意味着與.NET Remoting一起使用。從.NET遠程處理繼承WCF服務類似乎是一個壞主意......雖然我承認我不具備明確說出的專業知識。 – ErnieL 2012-01-11 03:42:09