WCF服务属性用于记录方法调用和exception

我需要在WCF服务中记录每个方法调用,并抛出任何exception。 这导致了许多冗余代码,因为每个方法都需要包含类似于此的样板:

[OperationContract] public ResultBase 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("Oops, the request failed", ex); } MyInfrastructure.LogEnd("Add", parameters); } 

有没有办法可以将所有这些逻辑封装到MyServiceLoggingBehaviorAttribute属性中,我可以将其应用于服务类(或方法),如下所示:

 [ServiceContract] [MyServiceLoggingBehavior] public class MyService { } 

注意#1

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

笔记2

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

注意#3

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

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

这有三个部分。

  1. 创建IOperationInvoker的实现,它将方法调用包装在所需的日志记录和error handling中。
  2. 创建IOperationBehavior的实现,该实现应用步骤1中的调用者。
  3. 创建一个inheritance自AttributeIServiceBehavior ,并应用步骤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这种实现将操作行为应用于服务; 它应该从Attributeinheritance,以便它可以作为属性应用于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); } } } } 

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

您需要做的就是使用AuditBehavior属性装饰您的WCF服务类或方法:

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

WCF扩展使用实现InvokeInvokeBegin / InvokeEndIOperationInvoker 。 你可以在这里查看代码。