WCF service attribute to log method calls and exceptions

最后都变了- 提交于 2019-11-27 03:52:12
McGarnagle

Yes, it is possible to encapsulate this kind of logging, using the extensibility points built into WCF. There are actually multiple possible approaches. The one I'm describing here adds an IServiceBehavior, which uses a custom IOperationInvoker, and does not require any web.config modifications.

There are three parts to this.

  1. Create an implementation of IOperationInvoker, which wraps the method invocation in the required logging and error-handling.
  2. Create an implementation of IOperationBehavior that applies the invoker from step 1.
  3. Create an IServiceBehavior, which inherits from Attribute, and applies the behavior from step 2.

Step 1 - IOperationInvoker

The crux of IOperationInvoker is the Invoke method. My class wraps the base invoker in a try-catch block:

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

Step 2 - IOperationBehavior

The implementation of IOperationBehavior simply applies the custom dispatcher to the operation.

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

    // (TODO stub implementations)
}

Step 3 - IServiceBehavior

This implementation of IServiceBehavior applies the operation behavior to the service; it should inherit from Attribute so that it can be applied as an attribute to the WCF service class. The implementation for this is standard.

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

You can try Audit.NET library with its Audit.WCF extension. It can log the WCF service interaction and is compatible with async calls.

All you need to do is decorate your WCF service class or methods with the AuditBehavior attribute:

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

The WCF extension uses an IOperationInvoker implementing Invoke and InvokeBegin/InvokeEnd. You can check the code here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!