0

我有正常的 WCF 服务,但方法很少。

我想在方法开始和结束时记录一些信息并执行一些操作。

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

但它不适用于异常。有,如果发生异常IErrorHandler,它允许我执行一些处理。缺点是我不知道它是从哪个方法抛出的。都是因为依附于服务行为,而不是操作本身。IErrorHandler

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

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

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

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

提前谢谢。

4

3 回答 3

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

于 2012-04-26T05:44:18.097 回答
1

我不知道有任何扩展可以实现您想要的,这里是广泛的列表。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 方面,您可以将其用于您想要的任何内容。

您应该尝试让您的错误处理程序不要做太多事情。

于 2012-04-26T04:27:06.020 回答
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 );
    }
}

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

于 2012-04-26T05:21:13.257 回答