微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – WCF服务属性来记录方法调用和异常

我需要记录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

我意识到这可以使用Aspect-oriented programming,但在C#中,唯一的方法修改字节码,这需要使用像PostSharp这样的第三方产品.我想避免使用商业图书馆.

笔记2

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

注3#

在某些情况下,WCF trace logging一个很好的选择,但是在这里不起作用,因为如上所述,我需要检查,并且在异常更改的情况下返回值.

解决方法

是的,可以使用 extensibility points built into WCF封装这种日志记录.实际上有多种可能的方法.我在这里描述的一个添加一个IServiceBehavior,它使用一个自定义IOperationInvoker,并且不需要任何web.config修改.

这有三个部分.

>创建一个IOperationInvoker的实现,它将方法调用包含在所需的日志记录和错误处理中.
>创建应用步骤1的调用者的IOperationBehavior的实现.
>创建一个继承自Attribute的IServiceBehavior,并应用步骤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,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的这种实现将操作行为应用于服务;它应该从属性继承,以便它可以作为属性应用于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);
            }
        }
    }
}

原文地址:https://www.jb51.cc/csharp/93851.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐