3

クラスがあります

public class MyService  
{  
   public IList<Exception> ExList {get; private set;}

   public bool HasErrors { get { return ExList.Count > 0; } }

   public MyMethod()
   {
       ExList.Clear();
       //- do some logic ---
   }

}

MyMethod() を呼び出して、エラーが発生したかどうかを確認します。このようなもの

var service = new MyService();

service.MyMethod();

if(service.HasErrors)
{
    // - do some logic
}

service.MyMethod();

if(service.HasErrors)
{
    // - do some logic
}

しかし、「ExList.Clear();」と書かなければなりません。MyService クラスのすべてのメソッドの行の手動。そして問題は - これを回避する解決策はありますか?

次のようなものが必要です

public class MyService  
{  
   public IList<Exception> ExList {get; private set;}

   public bool HasErrors { get { return ExList.Count > 0; } }

   private void Precondition()
   {
       ExList.Clear();
   }

   public MyMethod()
   {           
       //- do some logic ---
   }

}

また、メソッドの呼び出しごとに Precondition() が自動的に呼び出されます。

4

1 に答える 1

1

調べることができるもう1つのツールはPostSharpです。PostSharpは、カスタムアスペクト(属性)を定義できるAOPフレームワークです。

OnMethodBoundaryAspectに興味があるでしょう。以下のようなものでうまくいくはずです。args.Instanceは、「メソッドが実行されているインスタンス」になります

public class ClearListPrecondition : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        MyService service = args.Instance as MyService;
        if (service == null)
        {
            throw new InvalidOperationException(
              "This aspect can only execute on types of MyService");
        }

        service.ExList.Clear();
        base.OnEntry(args);
    }
}

次に、この側面でサービスメソッドを装飾します。

[ClearListPrecondition]
public void MyMethod()
{
}

このような些細な作業でAOPの道を選択する場合は、設計を再考することを強くお勧めします。

まず、例外をスローすることをお勧めしますが、主張する場合は、メソッドから結果を返すことができます。

例えば

public MethodResult MyMethod()
{
    ....
     if(errorHasOccured)
     {
          return new MethodResult() {Exceptions = exception};
     }
    ....
     return new MethodResult() {ResultOfMethod = ...};
}

public class MethodResult
{
   public IList<Exception> Exceptions {get; set;}
   public bool HasErrors { get { return ExList.Count > 0; } } 
   public string ResultOfMethod {get;set;}

}

コンシューマーは、メソッド呼び出しの結果を確認できます。

var service = new MyService();

var result1 = service.MyMethod();

if(result1.HasErrors)
{
    // - do some logic
}

var result2 = service.MyMethod();

if(result2.HasErrors) 
{
    // - do some logic
}

これにより、サービスがステートレスになる(したがってスレッドセーフになる)ときにサービスの状態をリセットする必要がなくなります。

于 2012-06-05T10:28:09.377 に答える