2012-06-23 87 views
2

我有一個產品服務。在每次調用服務時,我想調用一個方法。在這種情況下,我正在登錄。我正在尋找一種方法,而不是在每種方法中編寫使用語句。但是我仍然希望在每次通話中都會發生日誌記錄。我該怎麼做呢?你如何實現一個應該爲所有方法調用的基方法?

public class ProductService : IProductService 
{ 
    public IList<Product> GetProductsByBrand(int BrandID) 
    { 
     using (new Logging()) 
     { 
      // Get a list of products By Brand 
     } 
     return new List<Product>(); 
    } 

    public IList<Product> Search(string ProductName) 
    { 
     using (new Logging()) 
     { 
      // Search 
     } 
     return new List<Product>(); 
    } 

    public static string OrderProducts(IList<Order> Orders, Payment paymentDetials) 
    { 
     string AuthCode; 
     using (new Logging()) 
     { 
      // Order and get the AuthCode 
     } 
     AuthCode = ""; 
     return AuthCode; 
    } 
} 
+0

我不明白。 Logging類的代碼是什麼?或者你在問什麼?你想記錄什麼? – tallseth

+0

我認爲讓人難以理解的問題是您沒有存儲對新日誌記錄實例的引用。因此它不能在* using *塊中調用。這是意圖嗎?你是否想在每個服務方法之前調用一個方法,或者2)創建一個傳入並由每個服務方法使用的實例? – ErnieL

+0

對不起,我感到困惑。我只想在每種服務方法之前使用一種方法。 – katie77

回答

3

你聽說過AOP(Aspect Oriented Programming)嗎?這是一種將橫切關注點作爲可重用方面的方式,它們圍繞目標類型進行包裝,並在其包裝的方法之前或之後執行額外的處理。

http://en.wikipedia.org/wiki/Decorator_pattern

在一個WCF環境中,這通常通過將「行爲」爲您服務類完成。在這種情況下,我會建議IOperationBehavior接口使用實現IParameterInspector的屬性,以便在參數傳遞之前查看參數,創建並調用服務實例。這裏是一個有用的文章的鏈接,它更深入地討論了擴展wcf消息管道的選項。

http://msdn.microsoft.com/en-us/magazine/cc163302.aspx

//Attribute class 
public class LogOperationBehavior : Attribute, IOperationBehavior, IParameterInspector { 

public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { 
    return; 
} 

public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation) { 
    //clientOperation.ParameterInspectors.Add(new ClientParameterInspector());    
} 

public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation) { 
    dispatchOperation.ParameterInspectors.Add(this); 
} 

public void Validate(OperationDescription operationDescription) { 
    return; 
} 



#region IParameterInspector Members 

public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { 
    //perform logging after 
} 

public object BeforeCall(string operationName, object[] inputs) { 
    //perform logging before 
    return null; 
} 

#endregion 

}

public class BusinessOperation : IBusinessOperation { 

    //Apply to your service via an attribute 
    [LogOperationBehavior] 
    public DivideResponse DivideTwoNumbers(DivideRequest dr) {    
     return new DivideResponse() { 
      Answer = dr.Numerator/ dr.Demoninator2,    
     }; 
    } 
+0

這非常有趣。我在這裏有一個問題。與上面的實際問題無關。但是在行爲中,我可以訪問OperationContext嗎? – katie77

+0

我想你可以從IParameterInspector方法訪問它,因爲這些方法在調用服務時被調用。我認爲在構造服務描述時會調用OperationBehavior方法,並且無法訪問OperationContext。我沒有嘗試過。 –

1

您是否考慮過創建日誌代理?這將是這個樣子:

public class LoggingProductService : IProductService 
{ 
    private readonly IProductService _core; 

    public LoggingProductService(IProductService core) 
    { 
     _core = core; 
    } 

    public IList<Product> GetProductsByBrand(int BrandID) 
    { 
     Log("Getting products for brand " + BrandId); 
     return _core.GetProductsByBrand(BrandId); 
    } 

    //other IProductService methods here, all logging and delegating to _core 

    private void Log(string message) 
    { 
     using (var log = new Logging()) 
     { 
      log.Write(message); 
     } 
    } 
} 

當然,我並不完全瞭解你的日誌接口,所以在與正確的代碼適當的猜測填寫。您也可能不想經常創建和處理日誌記錄,我不知道。

+0

我的問題不在於日誌接口的實現。在上面的例子中,您可以爲Product Service實現的所有方法調用Log()方法。我的問題是有一種避免將Log()調用添加到產品Service的所有方法的方法。 – katie77

相關問題