是的,可以使用WCF 中内置的扩展点来封装这种日志记录。实际上有多种可能的方法。我在这里描述的添加了一个IServiceBehavior
,它使用了一个 custom 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);
}
}
}
}