C# .Net Core DI-同一类型的多个实例

C# .Net Core DI-同一类型的多个实例,c#,.net,dependency-injection,.net-core,inversion-of-control,C#,.net,Dependency Injection,.net Core,Inversion Of Control,首先,我看到了一些与我类似的话题,但我认为它们并不能真正回答我的问题 我正在创建一个应用程序,根据配置,它可以在多种模式下工作。该应用程序是从数据库到文件的简单数据导入/导出程序。它实际上可以传输数据: 在文件和数据库之间 在DB和另一个DB之间 第一种情况没有问题,第二种情况没有问题。我的应用程序包含以下类: filereader filewriter DbReader DbWriter 我想你们可以看到我如何把它们连接起来,从一个来源读到另一个来源写。当我想同时使用DbReader和

首先,我看到了一些与我类似的话题,但我认为它们并不能真正回答我的问题

我正在创建一个应用程序,根据配置,它可以在多种模式下工作。该应用程序是从数据库到文件的简单数据导入/导出程序。它实际上可以传输数据:

  • 在文件和数据库之间
  • 在DB和另一个DB之间
第一种情况没有问题,第二种情况没有问题。我的应用程序包含以下类:

  • filereader
  • filewriter
  • DbReader
  • DbWriter
我想你们可以看到我如何把它们连接起来,从一个来源读到另一个来源写。当我想同时使用
DbReader
DbWriter
时,会出现问题。由于它们都需要在其构造函数中使用
IDbClient
,因此我需要有一种方法向它们传递它的不同实例(因为
DbReader
将从数据库a读取,
DbWriter
将写入数据库B)。 实际上,我有更多的类需要
IDbClient
。例如,我有
DbDataCache
,它需要
IDbClient
的实例来连接数据库A,等等

我认为有几种方法可以实现这一目标。然而,我真的不喜欢他们中的任何一个。以下是我的想法:

  • 在将每个类注册到容器时,我可以“手动”注册它们-创建每个
    IDbClient
    ,创建依赖于它的每个类并将正确的实例传递给它们-我不喜欢它,因为我失去了注册的方便性,它变得相当复杂,并且有很多新的关键字使用

  • 我可以创建一个
    DbClientFactory
    并用一些名称注册
    IDbClient
    实例(比如
    DatabaseA
    DatabaseB
    )-我不喜欢它,因为需要
    IDbClient
    的类现在需要知道它们应该需要的名称。 因此,
    DbReader
    可能需要在其构造函数中有类似的想法

  • \u dbClient=\u dbFactory.Get(“DatabaseA”);
    
    DbWriter
    将具有:

    \u dbClient=\u dbFactory.Get(“DatabaseB”);
    

    你觉得怎么样?也许还有其他一些DI容器比.Net内核内置容器更适合我的需要?

    根据您的解释,我的理解是:;您的解决方案是在对DI容器的每个请求上提供IDbClient的新实例。如果这是真的,请尝试将您的服务注册为临时服务

     services.AddTransient<IMyService, MyService>();
    
    services.AddTransient();
    
    根据文件

    瞬态寿命


    如果有疑问,请暂时停止。这就是问题的症结所在。添加临时服务意味着每次请求服务时,都会创建一个新实例。

    根据您的解释,我的理解是:;您的解决方案是在对DI容器的每个请求上提供IDbClient的新实例。如果这是真的,请尝试将您的服务注册为临时服务

     services.AddTransient<IMyService, MyService>();
    
    services.AddTransient();
    
    根据文件

    瞬态寿命


    如果有疑问,请暂时停止。这就是问题的症结所在。添加临时服务意味着每次请求服务时,都会创建一个新实例。

    我将使用与.NET Core中的记录器相同的方法。因此,您通常不在DI中注册每个单独的记录器,而是注册ILoggerFactory,然后将其注入必要的类中,并使用
    CreateLogger(name)
    函数创建记录器

    因此,与日志记录类似,您可以在DI中注册IDbClientFactory的一些实现,在需要的地方注入它,并调用类似于
    dbClientFactory.CreateReader(dbName1)
    dbClientFactory.CreateWriter(dbName2)
    的东西来创建实际的读写器


    有趣的事。大约两周前,我们发表了一篇文章,完成了相同的任务:将数据从一些常见格式(JSON、XML)导入和导出到DB,反之亦然。该工具本身和底层库是完全开源的。因此,如果您发现有什么有用的东西,可以在您自己的项目中随意使用这些代码。

    我将使用与.NET Core中的记录器相同的方法。因此,您通常不在DI中注册每个单独的记录器,而是注册ILoggerFactory,然后将其注入必要的类中,并使用
    CreateLogger(name)
    函数创建记录器

    因此,与日志记录类似,您可以在DI中注册IDbClientFactory的一些实现,在需要的地方注入它,并调用类似于
    dbClientFactory.CreateReader(dbName1)
    dbClientFactory.CreateWriter(dbName2)
    的东西来创建实际的读写器


    有趣的事。大约两周前,我们发表了一篇文章,完成了相同的任务:将数据从一些常见格式(JSON、XML)导入和导出到DB,反之亦然。该工具本身和底层库是完全开源的。因此,如果您发现有什么有用的东西,可以在您自己的项目中随意使用这些代码。

    使您的
    IDbClient
    通用
    IDbClient
    ,并在writer请求
    IDbClient
    和reader请求
    IDbClient
    中分别为编写者和读者注册一个。在我看来,你的工厂想法也是一个有效的建议。@VidmantasBlazevicius我不喜欢仅仅为了DI的工作而改变我的课程的想法。在我看来,这样的DI是“侵入性的”,就像需要一个单独的工厂类一样。依我看,通用的是更清洁的设计。您还可以使用标记接口而不是泛型接口。无论如何,您都需要一种机制来注册同一混凝土的两个实例,然后识别它们