WCF服务属性登录方法调用和异常(WCF service attribute to log meth

2019-06-21 09:40发布

我要登录一个WCF服务的每个方法调用的要求,以及引发的任何异常。 这导致大量的冗余代码,因为每一种方法需要包括样板与此类似:

[OperationContract]
public ResultBase<int> Add(int x, int y)
{
    var parameters = new object[] { x, y }
    MyInfrastructure.LogStart("Add", parameters);
    try
    {
        // actual method body goes here
    }
    catch (Exception ex)
    {
        MyInfrastructure.LogError("Add", parameters, ex);
        return new ResultBase<int>("Oops, the request failed", ex);
    }
    MyInfrastructure.LogEnd("Add", parameters);
}

有没有一种方法可以让我封装了所有这种逻辑为属性MyServiceLoggingBehaviorAttribute ,我可以适用于服务类(或方法)是这样的:

[ServiceContract]
[MyServiceLoggingBehavior]
public class MyService
{
}

注意#1

我意识到,这是可以做到用面向方面编程 ,但在C#中做到这一点的唯一方法是修改字节码,这就需要使用第三方产品如PostSharp的。 我想避免使用商业库。

笔记2

需要注意的是Silverlight应用程序是服务的主要消费者。

注意#3

WCF跟踪记录是在某些情况下,一个很好的选择,而是因为,正如上面提到的,我需要检查它不会在这里工作,并在异常变化,则返回值的情况。

Answer 1:

是的,这是可能的封装这种记录的,使用内置到WCF的扩展点 。 实际上有多种可能的方法。 在一个我描述这里增加了一个IServiceBehavior ,它使用自定义IOperationInvoker ,并且不需要任何的web.config修改。

有三个环节进行。

  1. 创建的实现IOperationInvoker ,它包装在所需的记录和错误处理方法调用。
  2. 创建的实现IOperationBehavior ,从第1步中应用调用。
  3. 创建IServiceBehavior ,它从继承Attribute ,并从步骤2应用的行为。

第1步 - IOperationInvoker

的症结IOperationInvoker是Invoke方法。 我的类包装在一个try-catch块基地调用:

public class LoggingOperationInvoker : IOperationInvoker
{
    IOperationInvoker _baseInvoker;
    string _operationName;

    public LoggingOperationInvoker(IOperationInvoker baseInvoker, DispatchOperation operation)
    {
        _baseInvoker = baseInvoker;
        _operationName = operation.Name;
    }

    // (TODO stub implementations)

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        MyInfrastructure.LogStart(_operationName, inputs);
        try
        {
            return _baseInvoker.Invoke(instance, inputs, out outputs);
        }
        catch (Exception ex)
        {
            MyInfrastructure.LogError(_operationName, inputs, ex);
            return null;
        }
        MyInfrastructure.LogEnd("Add", parameters);
    }
}

第2步 - IOperationBehavior

实施IOperationBehavior简单地应用定制调度员操作。

public class LoggingOperationBehavior : IOperationBehavior
{
    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Invoker = new LoggingOperationInvoker(dispatchOperation.Invoker, dispatchOperation);
    }

    // (TODO stub implementations)
}

第3步 - IServiceBehavior接口

此实现IServiceBehavior适用的操作行为的服务; 它应该继承Attribute ,以便它可以作为WCF服务类的属性被应用。 造成这种情况的实施标准。

public class ServiceLoggingBehavior : Attribute, IServiceBehavior
{
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
        {
            foreach (OperationDescription operation in endpoint.Contract.Operations)
            {
                IOperationBehavior behavior = new LoggingOperationBehavior();
                operation.Behaviors.Add(behavior);
            }
        }
    }
}


Answer 2:

您可以尝试Audit.NET图书馆以其Audit.WCF扩展。 它可以记录的WCF服务交互,并与异步调用兼容。

所有你需要做的是装饰你的WCF服务类或方法AuditBehavior属性:

[AuditBehavior()]
public class OrderService : IOrderService
{ ... }

WCF的扩展使用的IOperationInvoker实现InvokeInvokeBegin / InvokeEnd 。 您可以检查代码在这里 。



文章来源: WCF service attribute to log method calls and exceptions