だから私はこれについて多くの研究をしましたが、「はい、それ」と言った答えは見つかりませんでした. 知識豊富な StackOverflow の皆さんが私を助けてくれることを願っています。
いくつかの異なるシナリオでこの問題に遭遇しました。C# アプリがあり、ログに記録したい重要なものがあるとします。
public class MyClass
{
...
public void ImportantMethod()
{
DoInterestingThing();
var result = SomethingElseImportant();
if (result == null)
{
logger.Log("I wasn't expecting that. No biggie.");
return;
}
MoreInterestingStuff();
}
私が興味を持っているのは、どこlogger
から取得するかです。
私が見ているように、私にはいくつかのオプションがあります。
- コンストラクターで MyClass に注入します。
- グローバルに利用可能なサービス ロケーターを使用して取得します。
- メソッド デコレーターと AOP を使用して、ログを記録します。
これらはどれも素晴らしいオプションのようには見えません。#3 は、メソッド呼び出し、入力パラメーター、および/またはスローされた例外の単純なトレースを行うだけでなく、ビジネス ロジックの途中でログを記録しているため、不可能に見えます。#2、単純に思えますが、単体テストは本当に難しいようです。もちろん、すべてを単体テストしたいと思います。#1 は問題なく動作しますが、ビジネス オブジェクト自体とは関係のないログ オブジェクトですべてのビジネス ロジックがごちゃごちゃになります。
上記のオプションのいずれかについて、代替案や考えはありますか? どうもありがとう!
編集:明確にするために、私はすでにDIの方法を知っており(Unityを使用しています)、優れたロギングフレームワークをすでに知っています(log4netを使用しています)。アプリケーション全体でアーキテクチャの意味でロギングを最もスマートな方法で使用する方法を考えてみてください。
* 編集 *
Mark Seeman の回答を解決策としてマークしました。アプリケーションを調べてみたところ、ロギング呼び出しのほとんどがデコレータと同じことを行っていることがわかりました。つまり、メソッドへのエントリ、スローされた例外をログに記録し、戻り値を終了します。
メソッド内で直接ログを記録する必要がある場合もありました。例は、何も返さないがException をスローしないメソッドで高速に失敗したい場合です。LogProvider
そのような場合、名前付きログ インスタンスを取得する参照 a を保持するシングルトンがあります。コードは次のようになります。
private ILog logger = LogProviderFactory.Instance.GetLogger(typeof(Foo));
LogProviderFactory にはSetProvider
、シングルトンを交換できるメソッドがあります。したがって、単体テストでは次のことができます。
// LogProviderFactory.Instance now is our mock
LogProviderFactory.SetProvider(MockLogProvider);
ロギング デコレータはシングルトンと同じ LogProvider (インジェクションによって取得) を使用するため、ロギングはシステム全体で統一されます。
したがって、最終的な解決策はほとんどがオプション 3 であり、ハイブリッド 2 でした (サービス ロケーター パターンですが、サービスはロケーターに「注入」されます)。
AOP
「アスペクト指向プログラミング」に関する限り、私は言語の限界に少しがっかりしました。AOP が将来のリリースで第一級市民として扱われることを願っています。
- PostSharp を試しましたが、自分のマシンで正しく実行できませんでした。さらに、システムに PostSharp をインストールして使用する必要があるという大きな制限がありました (ソリューションに付属の dll などを呼び出すだけではありません)。
- 私は LinFu を使用し、部分的に機能させることができました。ただし、いくつかの例で爆発しました。新しい 2.0 リリースはほとんど文書化されていないため、それがハードルでした。
- ただし、Unity とのインターフェイス インターセプトは、そのままで問題なく機能するようです。ログに記録したいもののほとんどがインターフェイスを実装するクラスにあったことは幸運でした。