用于记录和执行每个方法的操作的WCF扩展。 IErrorHandler没有方法的概念?

时间:2012-04-24 09:48:08

标签: .net wcf wcf-extensions

我的WCF服务很少,只有很少的方法。

我想记录一些信息,并在方法开头和最后执行一些操作。

通过实施IParameterInspector,我可以轻松地进行大量日志记录。方法BeforeCallAfterCall几乎可以为我提供所需的一切。

但它不适用于例外。有IErrorHandler,如果异常发生,我可以执行一些处理。缺点是我不知道它抛出了哪种方法。全部因为IErrorHandler附加到服务行为,而不是操作本身。

但是,我可以使用以下代码获取方法名称:

((System.Reflection.RuntimeMethodInfo)(exception.TargetSite)).Name == "MyMethod"

这对我来说不是一个好主意。

问题:伙计们,我可以使用其他任何WCF扩展来实现我的目标吗?你会建议使用旧的伙伴try-catch,也许可以将它包装成一些很好的语法,这样我就可以在开始和结束时执行操作?语法是什么?你为了类似的目的使用了什么?

非常感谢。

3 个答案:

答案 0 :(得分:3)

IOperationInvoker怎么样?

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 );
    }
}

缺点是您正在查看原始消息。它们映射到您的服务实现的操作。