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

必要なのは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 に答える
1

私はあなたが望むものを達成する拡張機能を知りません、そしてここに広範なリストがあります。IErrorHandlerは、必要なものを処理するための優れた方法です。

try/catchでコードを散らかさないでください。Try / Catchは、何らかの補正ロジックを実行することを意味し、ロギングはそのカテゴリに分類されません。

なぜキャストが必要なのか、なぜ平等をテストしているのかわかりません。メソッド情報の使用は問題ありません。もう1つのオプションは、StackTraceクラスを使用して、すべての呼び出しに関する情報を取得することです。

 public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            var s = new StackTrace(error);
            var faultyTowers = s.GetFrame(0);

        }

考慮すべきことの1つは、 PostSharpのようなものですが、無料ではありません($とパフォーマンス)。必要なものに使用できるすべての呼び出しにAOPアスペクトを注入できます。

エラーハンドラがあまり機能しないようにする必要があります。

于 2012-04-26T04:27:06.020 に答える