0

アプリの中核となるいくつかの拡張メソッドがあります。それらを使用して、中央の例外ハンドラーを介して OData サービスへのすべての呼び出しをルーティングします。次のようになります。

var results = Entites.Customers.Where(x=>x.IsActive).Invoke();

これInvoke()は私の拡張メソッドであり、すべてうまく機能します!

しかし、例外が発生したら、ログに記録したいと思います。

私が見つけた問題はILogger、クラス内で解決できないことですstatic(拡張メソッドを持つには、クラスが静的である必要があります)。

staticクラス内で統一管理されたインターフェイスを解決する方法はありますか? それとも依存性注入パターンはこの C# 機能に対応できないのでしょうか?

4

2 に答える 2

2

1 つのオプションは、静的クラスに実装を持たないことです。メソッドの実装を (拡張メソッドとしてではなく) 含む非静的クラスを作成し、拡張メソッドが非拡張実装を呼び出す以外に何もしないようにします。

それを行った後、実装は静的クラスではなくなります。

public static class MyExtension
{
    public static void Invoke<T>(this IQueryable<T> query) 
    {
        MyExtensionImplementation.Invoke(query);
    }
}

internal class MyExtensionImplementation
{
    public static void Invoke<T>(IQueryable<T> query) 
    {
        //actual work
    }
}
于 2013-03-28T16:49:06.187 に答える
1

悪いニュース - これを行う方法はありませんが、良いニュース - 拡張メソッド内で例外をログに記録する必要はありません。静的クラスの外で例外をスローし、適切な方法で処理するだけです。

IResult results;
try
{
  results = Entites.Customers.Where(x=>x.IsActive).Invoke();
}
catch(YourOwnException ex)
{
  Log(ex, "The Business logic error.");
}
catch(ArgumentException ex)
{
  Log(ex, "Invalid arguments.")
}
...
catch(Exception ex)
{
  Log(ex, "Unknown error.");
}

編集:

それらのほとんどは通信関連であり、拡張メソッドで処理されます。ビジネス関連のほんの一部が再スローされます。

例外が「通信関連」またはサードパーティである場合は、ログに記録する必要がない可能性があります。この場合TryInvoke()、ロギングなしのメソッドを作成します。このメソッドTRUEは、操作が成功した場合に戻り、OUTパラメーターを持ちます。それらをログに記録したい場合はILogger、メソッド内に注入する必要がありますInvoke()

if(Entites.Customers.Where(x=>x.IsActive).TryInvoke(out results))
{
  // Success
}
于 2013-03-28T17:05:17.573 に答える