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

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

问题描述

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

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

我意识到,这是可以做到用<一个href=\"http://stackoverflow.com/questions/4133569/how-to-log-method-calls-on-targets-marked-with-an-attribute\">Aspect-oriented编程,但在C#中做到这一点的唯一方法是修改字节code,它需要使用第三方产品一样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

<一个href=\"http://stackoverflow.com/questions/1178256/log-wcf-service-calls-with-parameter-information\">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接口,它使用一个自定义的<一个href=\"http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.aspx\"><$c$c>IOperationInvoker,而且不需要任何的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. 创建 IOperationInvoker 的实现,它包装在规定的记录和错误处理方法调用。

  2. 创建 IOperationBehavior ,从第1步中应用调用。
  3. 的实施
  4. 创建一个 IServiceBehavior接口,从属性继承,并从第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.

的<一个症结href=\"http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.aspx\">IOperationInvoker是调用方法。我的类包装基础调用在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)
    {
        IOperationInvoker _baseInvoker = baseInvoker;
        _operationName = operation.Name;
    }

    // (TODO stub implementations)

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

步骤2 - IOperationBehavior

的<一实施href=\"http://msdn.microsoft.com/en-us/library/system.servicemodel.description.ioperationbehavior.aspx\">IOperationBehavior简单地应用定制调度员的操作。

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, operationDescription, dispatchOperation);
    }

    // (TODO stub implementations)
}

步骤3 - IServiceBehavior接口

IServiceBehavior接口的这种实现应用操作行为的服务;它应该从属性继承,以便它可以作为对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天全站免登陆