1. ホーム
  2. c#

[解決済み] loggerをsingletonで持つのは良い習慣ですか?

2023-05-14 09:44:20

質問

コンストラクタにロガーを渡す癖があるのですが、どうすればいいですか?

public class OrderService : IOrderService {
     public OrderService(ILogger logger) {
     }
}

しかし、それではかなり困るので、以前からこのようなプロパティにしています。

private ILogger logger = NullLogger.Instance;
public ILogger Logger
{
    get { return logger; }
    set { logger = value; }
}

これもだんだん面倒になってきました。ベースクラスを使うこともできますが、Formクラスを使っているので、FormBaseなどが必要です。 ILoggerが公開されているシングルトンを持つことの欠点は何だろうかと考えますが、そうすれば、誰もがどこでloggerを取得できるかを知ることができます。

    Infrastructure.Logger.Info("blabla");

UPDATE: Merlynが正しく気づいたように、最初と2番目の例で私はDIを使っていることに言及すべきです。

どのように解決するのですか?

<ブロッククオート

これもうっとうしくなってきました。 DRY

その通りです。 しかし、どのタイプにも共通する横断的な問題に対して、できることは限られています。 あなたは を使う を使用しなければならないので、これらのタイプにプロパティを持たなければなりません。

では、どうすればいいのか見てみましょう。

シングルトン

シングルトンは恐ろしい <flame-suit-on> .

私は、あなたが2番目の例で行ったように、プロパティ注入にこだわることをお勧めします。 これは、マジックに頼らずにできる最高のファクタリングです。 シングルトンで依存関係を隠すよりも、明示的に依存関係を持つ方が良いのです。

しかし、もしシングルトンが、あなたがしなければならないすべてのリファクタリングを含む重要な時間を節約するならば(水晶玉の時間!)、あなたはそれらと共存することができるかもしれないと仮定します。 シングルトンの用途があるとすれば、それはこれかもしれません。 もし、あなたが を変更する場合、そのコストは高くなることを覚えておいてください。

この場合、他の人の回答をチェックするために Registry パターン (を登録するもの(説明を参照)、および(リセット可能な)シングルトンの ファクトリー を登録するものです。

それほど妥協せずに同じように動作する他の選択肢もあるので、まずそれらをチェックする必要があります。

Visual Studio のコード スニペット

あなたは Visual Studioのコード・スニペット を使用すると、その反復的なコードの入力を高速化することができます。 次のようなものを入力することができるようになります。 logger タブ と入力すれば、魔法のようにコードが表示されます。

AOPを使ったDRYオフ

を使うことで、プロパティインジェクションのコードを少し削除することができます。 のようなアスペクト指向プログラミング(AOP)フレームワークを使用することで、プロパティ注入のコードを少し取り除くことができます。 を使用して、その一部を自動生成することができます。

完成したらこんな感じになるかもしれません。

[InjectedLogger]
public ILogger Logger { get; set; }

また メソッドトレースのサンプルコード を使用して、自動的にメソッドの入口と出口コードをトレースすることもできます。これは、ロガーのプロパティの一部をまとめて追加する必要性をなくすかもしれません。 クラス レベル、またはネームスペース全体で属性を適用できます。

[Trace]
public class MyClass
{
    // ...
}

// or

#if DEBUG
[assembly: Trace( AttributeTargetTypes = "MyNamespace.*",
    AttributeTargetTypeAttributes = MulticastAttributes.Public,
    AttributeTargetMemberAttributes = MulticastAttributes.Public )]
#endif