2010-10-19 21 views
0

有沒有人對服務調用的常見錯誤處理有一個很好的例子?我剛開始一個新項目,我看到很多重複的代碼,我不喜歡並希望擺脫。我設法在其他幾個層次中這樣做,但在代理層調用服務時有點困難。該代碼是基本上結構如下:用WCF打包常見錯誤處理和跟蹤的服務調用

ResponseType MyProxyFunc(different, parameters) 
    { 
     var client = MyServiceClient(); 
     using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
     { 
      try 
      { 
      var response = client.MyRequest(different, parameters); 
       if (response.ErrorCode != Constants.OK) 
       { 
        ProxyCommon.ThrowError(besvarelseDS.Status[0].ErrorCode); 
       } 
      } 
      finally 
      { 
      ProxyCommon.CloseWcfClient(client); 
      } 
      return response; 
     } 
    } 

上面的代碼只是一個樣品,所述ProxyCommon對象是與各種方法的靜態類(可能不應該是抽象的而不是靜態的,而是這是另一個討論)。那麼有沒有人有一個很好的建議如何抽象這段代碼?我想在某種抽象方法中使用using,try/catch和if-statment,但由於MyServiceClient不同,參數個數不同,請求也不一樣,所以很難實現。

編輯:我以前用過的一個模式是使用通用Execute之類的函數public T Execute<T>(Func<T> func)。但在這種情況下,我無法得到這種類型的模式。

編輯#2:我已經更新了代碼,但我不是100%滿意,更喜歡60-75%。下面的代碼的問題在於它使用服務對象,並且它們對於所有服務都不相同,但是這將適用於在具有包裝的請求和響應對象的情況下對服務進行的服務調用。但我仍然不認爲這是解決問題的辦法:

public IList<PGSA.Data.Cargo.PGSAReportCargo> GetPGSAReport(DateTime dateFrom, DateTime? dateTo) 
{ 
    var reportService = new ReportServiceClient(); 
    var request = new GetPGSAReportRequest() 
    { 
     SystemCode = Settings.SystemID, 
     FromDate = dateFrom, 
     ToDate = dateTo 
    }; 
    var response = Execute(reportService, reportService.GetPGSAReport, request); 
    return response.PGSAReport.ToList(); 
} 

public L Execute<T, K, L>(T client, Func<K, L> serviceFunc, K request) 
    where T : ICommunicationObject 
    where K : RequestBase 
    where L : ResponseBase 
{ 
    using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
    { 
     try 
     { 
      L response = serviceFunc(request); 
      if (response.ErrorCode != Constants.OK) 
      { 
       ProxyCommon.ThrowError(response.ErrorCode); 
      } 
      return response; 
     } 
     finally 
     { 
      ProxyCommon.CloseWcfClient(client); 
     } 
    } 
} 

編輯#3:在編輯#2的ResponseBaseRequestBase是由服務定義的基類。

回答

1

你最後的辦法看起來不錯,我 - 我會如下稍微簡化一下:

public R Execute<T, R>(this T client, Func<R> serviceFunc) 
    where T : ICommunicationObject 
    where L : ResponseBase 
{ 
    using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
    { 
     try 
     { 
      R response = serviceFunc(); 
      if (response.ErrorCode != Constants.OK) 
      { 
       ProxyCommon.ThrowError(response.ErrorCode); 
      } 
      return response; 
     } 
     finally 
     { 
      ProxyCommon.CloseWcfClient(client); 
     } 
    } 
} 

在這裏使用它

reportService.Execute(() => reportService.GetPGSAReport(request)); 

想法是消除不需要的請求對象的依賴。

+0

你的答案是一個改進,因爲它允許「空」函數調用。但是,這不是我的問題的解決方案。我做了另一次更新,以明確ResponseBase和RequestBase是由服務定義的類,如果您正在使用多個服務,那些類將以不同的名稱空間結束,並且不能以這種通用的方式使用=>一個基本上每個服務代理執行''執行'功能。 – 2010-10-19 09:47:23

+0

你得到了答案,因爲你試了一下,我認爲這是關閉你可以得到:)。 – 2010-10-28 09:57:23