如何实现应该为所有方法调用的基本方法?

时间:2012-06-23 20:54:10

标签: wcf oop c#-4.0

我有产品服务。在每次调用Service时,我想调用一个方法。在这种情况下,我正在登录。我正在寻找一种方法,而不是在每个方法中编写using语句。但我仍然希望每次通话都能进行记录。我该怎么做?

    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;
    }
}

3 个答案:

答案 0 :(得分:3)

您听说过AOP(面向方面​​编程)吗?这是一种将交叉切割问题作为可重复使用的方面来实现的方法,这些方面包围目标类型并在它们包装的方法之前或之后执行其他处理。

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,              
        };
    }

答案 1 :(得分: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);
        }
    }
}

当然,我并不完全了解您的Logging界面,因此请使用正确的代码填写相应的猜测。您也可能不想创建和处理我经常不知道的日志记录。

答案 2 :(得分:0)

您可以创建动态代理。有关说明,请参阅此文章。 http://www.drdobbs.com/windows/184405378