记录方法调用和异常的 WCF 服务属性 [英] WCF service attribute to log method calls and exceptions

查看:22
本文介绍了记录方法调用和异常的 WCF 服务属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要记录 WCF 服务中的每个方法调用以及抛出的任何异常.这导致了很多冗余代码,因为每个方法都需要包含类似于这样的样板:

I have a requirement to log each method call in a WCF service, and any exceptions thrown. This has led to a lot of redundant code, because each method needs to include boilerplate similar to this:

[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 中,我可以像这样将其应用于服务类(或方法):

Is there a way I can encapsulate all this logic into an attribute MyServiceLoggingBehaviorAttribute, which I could apply to the service class (or methods) like this:

[ServiceContract]
[MyServiceLoggingBehavior]
public class MyService
{
}


注意 #1

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

I realize that this can be done using Aspect-oriented programming, but in C# the only way to do this is to modify bytecode, which requires the use of a third-party product like PostSharp. I would like to avoid using commercial libraries.

注意 #2

请注意,Silverlight 应用程序是服务的主要使用者.

Note that Silverlight applications are the primary consumers of the service.

注意 #3

WCF 跟踪日志记录 是一个不错的选择,但它在这里不起作用,因为如上所述,我需要检查,并且在异常更改的情况下,返回值.

WCF trace logging is a good option in some cases, but it doesn't work here because, as noted above, I need to inspect, and in the case of an exception change, the return value.

推荐答案

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

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.

分为三个部分.

  1. 创建 IOOperationInvoker 的实现,它将方法调用包装在所需的日志记录和错误处理中.
  2. 创建一个 IOOperationBehavior 实现,以应用步骤 1 中的调用程序.
  3. 创建一个 IServiceBehavior,它继承自 Attribute,并应用步骤 2 中的行为.
  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.

第 1 步 - IOperationInvoker

IOoperationInvoker 的关键是Invoke 方法.我的班级将基本调用程序包装在 try-catch 块中:

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

第 2 步 - IOperationBehavior

IOoperationBehavior 的实现仅适用操作的自定义调度程序.

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

第 3 步 - IServiceBehavior

IServiceBehavior 的这个实现将操作行为应用于服务;它应该从 Attribute 继承,以便它可以作为属性应用于 WCF 服务类.对此的实现是标准的.

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

这篇关于记录方法调用和异常的 WCF 服务属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆