1

私のDALモジュールの1つには、次のような形の重複した配管がたくさんあります。

while (retry)
{
...
try
{
   ...do something
   retry = false;
}
catch (SqlException sqlEx)
{
   // Retry only if -2 = Connection Time Out or 1205 = Deadlock
  if (sqlEx.Number == -2 || sqlEx.Number == 1205)
  {
      ..retry if attempt < max
  }
      ..log and rethrow exception
}
}

最近PostSharpを発見したので、これらの配管コードを属性に置き換えようとしています。

私の当初の計画は次のとおりでした: - OnMethodInvocationAspect を拡張し、メソッド呼び出し中にメソッド呼び出しイベント引数を記憶する - IOnExceptionAspect を実装し、OnException を実装して例外の種類をチェックし、再試行が必要な場合は、元の呼び出しからメソッド呼び出しイベント引数オブジェクトを使用します。

[Serializable]
public sealed class RetryAttribute : OnMethodInvocationAspect, IOnExceptionAspect
{
    [NonSerialized]
    private MethodInvocationEventArgs m_initialInvocationEventArgs = null;

    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        if (m_initialInvocationEventArgs == null)
            m_initialInvocationEventArgs = eventArgs;

        base.OnInvocation(eventArgs);
    }

    public void OnException(MethodExecutionEventArgs eventArgs)
    {
        // check if retry is necessary
        m_initialInvocationEventArgs.Proceed();
    }
}

しかし、IOnExceptionAspect を追加すると、OnInvocation メソッドは起動されなくなりました。

ここで何をする必要があるか知っている人はいますか?それとも、私が使用すべきより適切な側面がありますか?

ありがとう、

4

3 に答える 3

4

2 つのアスペクト インターフェイス (この場合は IOnMethodInvocation と IOnExceptionAspect) を実装するアスペクトを持つことはできません。ウィーバーは任意のインターフェースを 1 つ取り、アスペクトを実装します。

目的を達成するために必要なのは OnMethodInvocationAspect だけだと思います。OnInvocation ハンドラに for ループと try-catch を入れてみませんか?

于 2009-08-21T14:07:05.780 に答える
1

かなり古い質問ですが、役立つ可能性のあるアプローチを共有したいと思います。また、このパラダイムをうまく利用しています。以下のコードを見てください。あなたがすることは、実際にはMethodLevelAspect「アドバイス」から継承して使用することです。

OnExceptionargs.Proceed()エラーをスローするのに役立ちません。そのため、追加の try-catch ブロックを で直接使用しましたOnInvoke

[Serializable]
public class MyAspectAttribute : MethodLevelAspect
{
    object exceptionReturn = null;

    public MyAspectAttribute(object ExceptionReturn) : base()
    {
    }

    [OnMethodInvokeAdvice, SelfPointcut]
    [AdviceDependency(AspectDependencyAction.Order, AspectDependencyPosition.Before, "OnEntry")]
    public void OnInvoke(MethodInterceptionArgs args)
    {
        try
        {
            args.Proceed();
        }
        catch (Exception exc)
        {
            // do logging here
            args.ReturnValue = exceptionReturn;
        }
    }

    [OnMethodExceptionAdvice, SelfPointcut]
    public void OnException(MethodExecutionArgs args)
    {
    }

    [OnMethodEntryAdvice, SelfPointcut]
    public void OnEntry(MethodExecutionArgs args)
    {
    }

    [OnMethodExitAdvice, SelfPointcut]
    [AdviceDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "OnInvoke")]
    [AdviceDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "OnEntry")]
    public void OnExit(MethodExecutionArgs args)
    {
         // your exit statements, such as committing transaction etc.
    }
}
于 2012-04-18T06:30:22.427 に答える