web-dev-qa-db-ja.com

静的クラスからのASP.NET Core Web APIロギング

私は自分のコントローラーで依存性注入を使用してうまくログを記録していますが、今は何かを記録する必要がありますfrom静的クラス。

どうすればfrom静的クラスを記録できますか?

静的であるため、依存関係の注入は使用できません。また、ログファイル内のクラスの名前が間違っているため、既存のロガーオブジェクトを静的クラスに渡すだけではできません。

つまり、静的クラス内のロガーファクトリーからロガーを取得するにはどうすればよいですか?

私は同様の質問に出くわし、彼らは静的クラスのロガーファクトリーに関する記事を指しましたが、それはパラメーターとして静的クラスを受け入れないため、新しいロガーを取得できないため実際には機能しません:

「静的型は型引数として使用できません」

15
JohnC

解決策は、起動時に初期化されたユーティリティの静的クラスでLoggerFactoryへの静的参照を持つことです。

/// <summary>
    /// Shared logger
    /// </summary>
    internal static class ApplicationLogging
    {
        internal static ILoggerFactory LoggerFactory { get; set; }// = new LoggerFactory();
        internal static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();        
        internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName);

    }

Startup.csで初期化するもの:

 public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, IHostingEnvironment hostingEnvironment)
        {
            _log = logger;
            _hostingEnvironment = hostingEnvironment;
            Util.ApplicationLogging.LoggerFactory = logFactory;//<===HERE

        }

その後、次のように静的クラスから使用するロガーを作成できます。

internal static class CoreJobSweeper
    {
        private static ILogger log = Util.ApplicationLogging.CreateLogger("CoreJobSweeper");
28
JohnC

静的なLoggerFactoryインスタンスを使用するには、ジェネリック型パラメーターではなく、Type型の通常のパラメーターを受け入れる次の拡張メソッドを使用します。 CreateLogger(ILoggerFactory、Type) =

すなわち、loggerFactory.CreateLogger(typeof(T))ではなくloggerFactory.CreateLogger<T>()

3
Adrian

まず、私は NightOwl888 に同意します。

ただし、オプションとして(これを回避策と考えて)メソッドパラメーター=>を介してILogger依存関係を注入することができるため、この静的メソッドを呼び出すクラスはILoggerの正しい実装を提供する必要があります。 。

static class YourClass
{
    public static void DoSomething(ILogger logger)
    {
         // do something
         // call log.Log();
    }
}
1
Set

静的クラスからログを記録するにはどうすればよいですか?

あなたはしません。

ログに記録するのに十分な重要なことをしている場合は、サービス内にある必要があります。次に、コンストラクターを介してロガーを注入することでログを記録できます。

静的なクラスとメソッドは便利ですが、変更される可能性が低く、依存関係を必要としないことを保証の単純なロジック用に予約する必要があります。この質問をしなければならない場合は、明らかにその線を越えています。

より有用な質問は:なぜクラスが静的なのですか?

.NET CoreのDIコンテナ(および私が見た他のすべてのコンテナ)には、静的クラス(アプリケーション全体の1つのインスタンス)と同じように動作するシングルトンライフスタイルがあります)。それに応じてサービスを登録するだけで、残りはDI​​コンテナが処理します。

services.AddSingleton<IMyService, MyService>();

これにより、サービスを静的にする必要がなくなります。言うまでもなく、ロガーが必要な場合など、依存関係をそれらに挿入できます。

拡張メソッド

拡張メソッドは非常に便利ですが、ビジネスロジックに使用することはお勧めしません。ただし、HTMLヘルパーは拡張メソッドを使用して実装されるため、DIを使用する必要がある場合は問題があります。 ASP.NET Coreでは、依存関係が必要な場合に拡張メソッドではなく、DIフレンドリーな コンポーネントを表示 にすることが可能になりました(推奨)。

しかし、もしあなたが絶対にそれを拡張方法にしたいような問題の一つを持っているなら、質問はありません。 この手法 を使用して、拡張メソッドでDIを使用することができます。どこでもそれを行うことはお勧めしませんが、選択肢がない場合(MVC 5など)、これは機能します。ただし、拡張メソッドのみが静的であることを確認してください。

1
NightOwl888