[英]WCF service attribute to log method calls and exceptions
I have a requirement to log each method call in a WCF service, and any exceptions thrown. 我需要在WCF服务中记录每个方法调用,并抛出任何异常。 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);
}
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: 有没有办法可以将所有这些逻辑封装到MyServiceLoggingBehaviorAttribute
属性中,我可以将其应用于服务类(或方法),如下所示:
[ServiceContract]
[MyServiceLoggingBehavior]
public class MyService
{
}
Note #1 注意#1
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. 我意识到这可以使用面向方面的编程来完成,但在C#中,唯一的方法是修改字节码,这需要使用像PostSharp这样的第三方产品。 I would like to avoid using commercial libraries. 我想避免使用商业图书馆。
Note #2 笔记2
Note that Silverlight applications are the primary consumers of the service. 请注意,Silverlight应用程序是该服务的主要使用者。
Note #3 注意#3
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跟踪日志记录是一个不错的选择,但它在这里不起作用,因为如上所述,我需要检查,并且在异常更改的情况下,返回值。
Yes, it is possible to encapsulate this kind of logging, using the extensibility points built into WCF . 是的,可以使用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. 我在这里描述的那个添加了一个IServiceBehavior
,它使用自定义IOperationInvoker
,并且不需要任何web.config修改。
There are three parts to this. 这有三个部分。
IOperationInvoker
, which wraps the method invocation in the required logging and error-handling. 创建IOperationInvoker
的实现,它将方法调用包装在所需的日志记录和错误处理中。 IOperationBehavior
that applies the invoker from step 1. 创建IOperationBehavior
的实现,该实现应用步骤1中的调用者。 IServiceBehavior
, which inherits from Attribute
, and applies the behavior from step 2. 创建一个继承自Attribute
的IServiceBehavior
,并应用步骤2中的行为。 The crux of IOperationInvoker is the Invoke
method. IOperationInvoker的关键是Invoke
方法。 My class wraps the base invoker in a try-catch block: 我的类将基本调用程序包装在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);
}
}
The implementation of IOperationBehavior simply applies the custom dispatcher to the operation. IOperationBehavior的实现只是将自定义调度程序应用于操作。
public class LoggingOperationBehavior : IOperationBehavior
{
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Invoker = new LoggingOperationInvoker(dispatchOperation.Invoker, dispatchOperation);
}
// (TODO stub implementations)
}
This implementation of IServiceBehavior
applies the operation behavior to the service; IServiceBehavior
这种实现将操作行为应用于服务; it should inherit from Attribute
so that it can be applied as an attribute to the WCF service class. 它应该从Attribute
继承,以便它可以作为属性应用于WCF服务类。 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. 您可以尝试使用Audit.WCF扩展的Audit.NET库。 It can log the WCF service interaction and is compatible with async calls. 它可以记录WCF服务交互并与异步调用兼容。
All you need to do is decorate your WCF service class or methods with the AuditBehavior
attribute: 您需要做的就是使用AuditBehavior
属性装饰您的WCF服务类或方法:
[AuditBehavior()]
public class OrderService : IOrderService
{ ... }
The WCF extension uses an IOperationInvoker
implementing Invoke
and InvokeBegin
/ InvokeEnd
. WCF扩展使用实现Invoke
和InvokeBegin
/ InvokeEnd
的IOperationInvoker
。 You can check the code here . 你可以在这里查看代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.