web-dev-qa-db-ja.com

ASP.NETの依存性注入とファクトリパターンを使用したサービスの受け渡し

私はASP.NETCoreを使用しています。このようなログメカニズムはフレームワークによってすでに提供されていることは知っていますが、これを使用して問題を説明しています。

ロギングのタイプがわからないため(DBに格納されているため)、一種のファクトリパターンを使用してLoggerクラスを構築しています。

ILogger契約

Log(string msg)

次に、LoggerFactoryは、DBから渡されたパラメータに基づいてロガーを作成した後、ILoggerを返します。

public class LoggerFactory
{
    public static Contracts.ILogger BuildLogger(LogType type)
    {
        return GetLogger(type);
    }

//other code is omitted, GetLogger will return an implementation of the related logger

さて、ロガーを使用する必要があるときは、次のようにする必要があります。

  public class MyService
{
    private ILogger _logger
    public MyService()
    {
        _logger = LoggerFactory.BuildLogger("myType");
    }

ただし、インスタンス化せずにクラスを保持するつもりです。MyServiceでコンストラクタDIを使用する必要があり、Startupへのすべての依存関係を挿入する必要があります。

    services.AddTransient<Contracts.ILogger, LoggerFactory.BuildLogger("param") > ();

しかし、これは機能しません。具体的な実装を渡す必要があります。 DIを使用してそれを機能させる方法、それを実装するためのより良いアプローチはありますか?

6
Hussein Salman

あなたのアプローチにはいくつかの誤りがあります:

代わりに、サービスは次のようになります。

public class MyService
{
    private ILogger _logger;
    public MyService(ILogger logger)
    {
        _logger = logger;
    }
}

これにより、ILoggerに依存するすべてのコンシューマーが劇的に簡素化されます。これは、ILoggerに対して正しいMyServiceを取得することが、この知識を持つ正しい場所である Composition Root の責任になることも意味します。

ただし、組み込みコンテナーはILoggerライブラリに他のコンストラクターの依存関係も自動配線させながら、.

ASP.NET Core DIコンテナーでは、デリゲートを使用してのみサービスを手動で配線できます。例えば:

services.AddTransient<MyService>(c => new MyService(
    BuildLogger(typeof(MyService).Name),
    c.GetRequiredService<ISomeOtherDependency>(),
    c.GetRequiredService<IYetAnotherOne>());
18
Steven