web-dev-qa-db-ja.com

ILoggerまたはILoggerFactoryをAspNet Coreのコンストラクターに渡しますか?

MSドキュメントの記事 「ASP.NET Coreでのロギングの概要」 は、コンストラクター注入の2つの例を示しています。

  • ILoggerを使用

    _private readonly ILogger _logger;   
    public TodoController(ILogger<TodoController> logger)  
    { 
        _logger = logger;   
    }
    _
  • およびILoggerFactory

    _private readonly ILogger _logger;  
    public TodoController( ILoggerFactory loggerFactory)  
    {  
        _logger = loggerFactory.CreateLogger<TodoController>();  
    }
    _

私の質問は、コントローラから呼び出されたchildクラスに何を渡すべきかです

  • ILoggerFactoryをコントローラーから呼び出された各子クラスに渡し、各クラスでLoggerFactoryExtensions.CreateLogger<MyChildClass>()を呼び出します

  • 親コントローラーの_ILogger<MyController>_をコントローラーから作成された非汎用パラメーターILoggerを持つ各子クラスに渡します。

ログでは、すべてのクラスが親コントローラのカテゴリ「MyController」を使用するのではなく、クラスごとに個別のカテゴリ「MyChildClass」を表示することを好みます。
ただし、各オブジェクトの作成におけるCreateLoggerは高価な操作になる場合があります(例: https://github.com/aspnet/Logging/issues/524

どのオプションをお勧めしますか?他のアプローチを提案できますか?

20

これは設計上の問題です。

とにかく、コントローラーは子クラスを作成しないでください。これは、コントローラーが対処すべき問題ではなく、SRP(単一責任原則)に反するものです。

私の質問は、コントローラーから呼び出された子クラスに何を渡す必要があるかです

ロガーを分離することが望ましい場合は、子(依存)クラスに独自のロガーを持たせる以外に選択肢はありません。

子クラスに独自のロガーを注入させる

public class TodoRepository : ITodoRepository {
    private readonly ILogger logger; 

    public TodoRepository(ILogger<TodoRepository> logger) { 
        this.logger = logger;   
    }

    //...
}

そして、子クラスをコントローラーに注入します。

public class TodoController : Controller {
    private readonly ILogger logger;
    private readonly ITodoRepository todoRepository;

    public TodoController(ILogger<TodoController> logger, ITodoRepository todoRepository) {
        this.logger = logger;   
        this.todoRepository = todoRepository;
    }

    //...
}

こうすることで、子クラスが解決されてコントローラーに挿入されるときに、子ロガーが解決されます。

12
Nkosi