[英].Net Core DI - multiple instances of the same type
First of all, I saw some topics similar to mine, however I think they don't really answer my issue. 首先,我看到了一些类似于我的主题,但是我认为它们并不能真正回答我的问题。
I am creating an application, which, depending on configuration can work in multiple modes. 我正在创建一个应用程序,根据配置可以在多种模式下工作。 The app is a simple importer/exporter of data from database to files. 该应用程序是从数据库到文件的简单数据导入/导出。 It can actually transfer data: 它实际上可以传输数据:
The first case is not problematic, the second one is. 第一种情况没有问题,第二种情况有问题。 My application has classes like: 我的应用程序具有以下类:
FilesReader
FilesWriter
DbReader
DbWriter
I think you can see how I can connect them together to read from one source and write to another. 我认为您可以看到如何将它们连接在一起以从一个来源读取并写入另一个来源。 Problem appears when I want to use DbReader
and DbWriter
at the same time. 当我想同时使用DbReader
和DbWriter
时出现问题。 Since both of them require IDbClient
in their constructors, I need to have a way to pass to them different instances of it (since DbReader
will read from Database A and DbWriter
will write to database B). 由于他们两个都需要在其构造函数中使用IDbClient
,因此我需要有一种方法可以将它们的不同实例传递给他们(因为DbReader
将从数据库A中读取,而DbWriter
将从数据库B中写入)。 In reality, I actually have more classes that need IDbClient
. 实际上,实际上我有更多需要IDbClient
类。 For example I have DbDataCache
, which will need instance of IDbClient
to connect with Database A, and so on. 例如,我有DbDataCache
,它将需要IDbClient
实例才能与数据库A连接,依此类推。
There are a few ways that I think of how it could be achieved. 我认为有几种方法可以实现。 However, I don't really like any of them. 但是,我真的不喜欢其中任何一个。 Here're my ideas: 这是我的想法:
While registering each class to the container, I could register them "manually" - create each IDbClient
, create each class that depends on it and pass the right instances to them - I don't like it, because I lose the easiness of registration, it becomes quite complicated and there is a lot of new
keyword use. 在将每个类注册到容器时,我可以“手动”注册它们-创建每个IDbClient
,创建依赖于它的每个类并将正确的实例传递给它们-我不喜欢它,因为我失去了注册的便利性,它变得非常复杂,并且有很多new
关键字使用。
I could create a DbClientFactory
and register IDbClient
instances with some names (like DatabaseA
and DatabaseB
) - I don't like it, because the classes that need IDbClient
will now need to know the name that they should require. 我可以创建一个DbClientFactory
并使用一些名称(例如DatabaseA
和DatabaseB
)注册IDbClient
实例-我不喜欢它,因为需要IDbClient
的类现在需要知道它们应使用的名称。 So, probably DbReader
would need to have somethink like this in its constructor 因此, DbReader
可能需要在其构造函数中具有这种DbReader
_dbClient = _dbFactory.Get("DatabaseA");
while DbWriter
will have: 而DbWriter
将具有:
_dbClient = _dbFactory.Get("DatabaseB");
What do you think? 你怎么看? Maybe there is some other DI container that would be more suitable for my needs than the .Net Core built-in one? 也许还有一些其他的DI容器比.Net Core内置容器更适合我的需求?
As per my understanding from your explaination is that; 根据您的解释,我的理解是: Your solution would be to have new instance of IDbClient served on each request to DI Container. 您的解决方案是在对DI Container的每个请求中提供新的IDbClient实例。 If that's true try to register your service as Transient 如果是这样,请尝试将您的服务注册为Transient
services.AddTransient<IMyService, MyService>();
as per docs 根据文档
Transient Lifetime 瞬态寿命
If in doubt, make it transient. 如有疑问,请使其瞬态。 That's really what it comes down to. 这才是真正的原因。 Adding a transient service means that each time the service is requested, a new instance is created. 添加临时服务意味着每次请求该服务时,都会创建一个新实例。
I would use the same approach that is used for loggers in .NET Core itself. 我将使用与.NET Core本身中的记录器相同的方法。 So, instead of registering in DI each separate logger you usually register ILoggerFactory and then inject it in the necessary class and create a logger with CreateLogger(name)
function. 因此,通常不用注册DI单独的记录器,而通常注册ILoggerFactory,然后将其注入必要的类并使用CreateLogger(name)
函数创建一个记录器。
So, the similar way as with logging you can register in DI some implementations of IDbClientFactory, inject it where it's needed and call something like dbClientFactory.CreateReader(dbName1)
or dbClientFactory.CreateWriter(dbName2)
to create actual reader or writers. 因此,与日志记录类似,您可以在DI中注册IDbClientFactory的某些实现,将其注入所需的位置,然后调用dbClientFactory.CreateReader(dbName1)
或dbClientFactory.CreateWriter(dbName2)
来创建实际的读取器或dbClientFactory.CreateWriter(dbName2)
器。
Funny thing. 有趣的事情。 About 2 weeks ago we had published a .NET Core global tool which does the same tasks: importing and exporting the data from some common formats (JSON, XML) to DB and vice versa. 大约两周前,我们发布了一个.NET Core全局工具 ,该工具执行相同的任务:将数据从某些常见格式(JSON,XML)导入和导出到DB,反之亦然。 The tool itself and the underlying library are totally open-source and published on GitHub . 该工具本身和底层库是完全开源的,并在GitHub上发布 。 So, feel free to use that code in your own project if you find there something useful. 因此,如果发现有用的东西,请随时在您自己的项目中使用该代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.