我的WCF服务很少,只有很少的方法。
我想记录一些信息,并在方法开头和最后执行一些操作。
通过实施IParameterInspector
,我可以轻松地进行大量日志记录。方法BeforeCall
和AfterCall
几乎可以为我提供所需的一切。
但它不适用于例外。有IErrorHandler
,如果异常发生,我可以执行一些处理。缺点是我不知道它抛出了哪种方法。全部因为IErrorHandler
附加到服务行为,而不是操作本身。
但是,我可以使用以下代码获取方法名称:
((System.Reflection.RuntimeMethodInfo)(exception.TargetSite)).Name == "MyMethod"
这对我来说不是一个好主意。
问题:伙计们,我可以使用其他任何WCF扩展来实现我的目标吗?你会建议使用旧的伙伴try-catch,也许可以将它包装成一些很好的语法,这样我就可以在开始和结束时执行操作?语法是什么?你为了类似的目的使用了什么?
非常感谢。
答案 0 :(得分:3)
public class NHibernateOperationInvoker : IOperationInvoker {
private readonly IOperationInvoker _invoker;
private readonly String _operationName;
public NHibernateOperationInvoker(IOperationInvoker invoker, String operationName) {
_invoker = invoker;
_operationName = operationName;
}
public Object[] AllocateInputs() {
return _invoker.AllocateInputs();
}
public Object Invoke(Object instance, Object[] inputs, out Object[] outputs) {
using (var context = NHibernateContext.CreateNew()) {
try {
var result = _invoker.Invoke(instance, inputs, out outputs);
context.Commit();
return result;
} catch(Exception ex) {
Debug.Fail("Operation " + _operationName + " failed with " + ex.Message);
}
}
}
public IAsyncResult InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state) {
throw new NotImplementedException("NHibernateOperationInvoker.InvokeBegin");
}
public Object InvokeEnd(Object instance, out Object[] outputs, IAsyncResult result) {
throw new NotImplementedException("NHibernateOperationInvoker.InvokeEnd");
}
public Boolean IsSynchronous {
get { return true; }
}
}
使用IOperationBehavior附加dispatchOperation.Invoker = new NHibernateOperationInvoker(dispatchOperation.Invoker, dispatchOperation.Name);
答案 1 :(得分:1)
我不知道任何可以实现您想要的扩展和here is extensive list。 IErrorHandler是处理所需内容的好方法。
请勿使用try / catch丢弃代码。 Try / Catch意味着您将执行一些补偿逻辑,并且日志记录不属于该类别。
我不确定你为什么需要演员或为什么要测试平等。使用方法信息很好。另一个选择是使用StackTrace类来获取有关每个调用的信息,例如
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var s = new StackTrace(error);
var faultyTowers = s.GetFrame(0);
}
要考虑的一件事是PostSharp,但它不是免费的($和性能)。您可以为每个可以使用的呼叫注入AOP方面。
您应该尝试让错误处理程序不要做太多。
答案 2 :(得分:1)
你想要的是IDispatchMessageInspector
如果有任何内容被发送回客户端,则会调用BeforeSendReply。如果您将其作为MessageInspector添加到dispatchRuntime中,则此方法有效:
public class MessageLogger : IDispatchMessageInspector
{
public object AfterReceiveRequest( ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext )
{
Log("Begin: " + request.Headers.Action );
return request;
}
public void BeforeSendReply( ref System.ServiceModel.Channels.Message reply, object correlationState )
{
System.ServiceModel.Channels.Message request = (System.ServiceModel.Channels.Message)correlationState;
Log("End: " + request.Headers.Action );
}
}
缺点是您正在查看原始消息。它们映射到您的服务实现的操作。