我要登录一个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
我意识到,这是可以做到用面向方面编程 ,但在C#中做到这一点的唯一方法是修改字节码,这就需要使用第三方产品如PostSharp的。 我想避免使用商业库。
笔记2
需要注意的是Silverlight应用程序是服务的主要消费者。
注意#3
WCF跟踪记录是在某些情况下,一个很好的选择,而是因为,正如上面提到的,我需要检查它不会在这里工作,并在异常变化,则返回值的情况。
是的,这是可能的封装这种记录的,使用内置到WCF的扩展点 。 实际上有多种可能的方法。 在一个我描述这里增加了一个IServiceBehavior
,它使用自定义IOperationInvoker
,并且不需要任何的web.config修改。
有三个环节进行。
- 创建的实现
IOperationInvoker
,它包装在所需的记录和错误处理方法调用。 - 创建的实现
IOperationBehavior
,从第1步中应用调用。 - 创建
IServiceBehavior
,它从继承Attribute
,并从步骤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
适用的操作行为的服务; 它应该继承Attribute
,以便它可以作为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.NET图书馆以其Audit.WCF扩展。 它可以记录的WCF服务交互,并与异步调用兼容。
所有你需要做的是装饰你的WCF服务类或方法AuditBehavior
属性:
[AuditBehavior()]
public class OrderService : IOrderService
{ ... }
WCF的扩展使用的IOperationInvoker
实现Invoke
和InvokeBegin
/ InvokeEnd
。 您可以检查代码在这里 。