WCF服务属性登录方法调用和异常 [英] WCF service attribute to log method calls and exceptions
问题描述
我要登录一个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$c$c>,而且不需要任何的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.
有三个部分这一点。
- 创建
IOperationInvoker
的实现,它包装在规定的记录和错误处理方法调用。 - 创建
IOperationBehavior
,从第1步中应用调用。 的实施 - 创建一个
IServiceBehavior接口
,从属性
继承,并从第2步适用的行为。
- Create an implementation of
IOperationInvoker
, which wraps the method invocation in the required logging and error-handling. - Create an implementation of
IOperationBehavior
that applies the invoker from step 1. - Create an
IServiceBehavior
, which inherits fromAttribute
, 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屋!