17

WCF サービスの各メソッド呼び出しとスローされた例外をログに記録する必要があります。各メソッドには次のようなボイラープレートを含める必要があるため、これは多くの冗長なコードにつながりました。

[OperationContract]
public ResultBase<int> Add(int x, int y)
{
    var parameters = new object[] { x, y }
    MyInfrastructure.LogStart("Add", parameters);
    try
    {
        // actual method body goes here
    }
    catch (Exception ex)
    {
        MyInfrastructure.LogError("Add", parameters, ex);
        return new ResultBase<int>("Oops, the request failed", ex);
    }
    MyInfrastructure.LogEnd("Add", parameters);
}

このすべてのロジックを属性MyServiceLoggingBehaviorAttributeにカプセル化する方法はありますか?これを次のようにサービス クラス (またはメソッド) に適用できます。

[ServiceContract]
[MyServiceLoggingBehavior]
public class MyService
{
}

注#1

これはアスペクト指向プログラミングを使用して実行できることを認識していますが、C# でこれを行う唯一の方法はバイトコードを変更することであり、PostSharp などのサードパーティ製品を使用する必要があります。商用ライブラリの使用は避けたいと思います。

注#2

Silverlight アプリケーションはサービスの主な利用者であることに注意してください。

注3

WCF トレース ログは場合によっては適切なオプションですが、上記のように、戻り値を検査する必要があり、例外が変更された場合は戻り値が必要になるため、ここでは機能しません。

4

2 に答える 2

28

はい、 WCF に組み込まれている拡張ポイントを使用して、この種のログをカプセル化することができます。実際には複数の可能なアプローチがあります。ここで説明しているIServiceBehaviorものは、カスタムを使用する を追加し、IOperationInvokerweb.config の変更を必要としません。

これには 3 つの部分があります。

  1. の実装を作成しますIOperationInvoker。これは、必要なロギングとエラー処理でメソッド呼び出しをラップします。
  2. IOperationBehaviorステップ 1 の呼び出し元を適用する の実装を作成します。
  3. 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は、操作の動作がサービスに適用されます。AttributeWCF サービス クラスに属性として適用できるように、から継承する必要があります。この実装は標準です。

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);
            }
        }
    }
}
于 2012-12-01T01:44:09.343 に答える
5

Audit.WCF拡張機能を使用して、 Audit.NETライブラリを試すことができます。WCF サービスの対話をログに記録でき、非同期呼び出しと互換性があります。

必要なことは、WCF サービス クラスまたはメソッドを次のAuditBehavior属性で装飾することだけです。

[AuditBehavior()]
public class OrderService : IOrderService
{ ... }

WCF 拡張機能は、IOperationInvoker実装InvokeInvokeBegin/を使用しInvokeEndます。コードはこちらで確認できます。

于 2018-01-15T06:36:34.627 に答える