如何在 C# .net 6 应用程序中使用依赖注入来传递具有相同接口的同一对象的不同实例?
How do I use Dependency Injection in C# .net 6 application to pass in different instances of the same object with same interface?
我正在 Visual Studio 使用 c# 和 .NET 6 创建一个 Azure Function App。
我创建了一个实现接口 ICosmosDBService 的服务 (CosmosDBService):
public class CosmosDbService : ICosmosDbService
{
private Container? _container = null;
public CosmosDbService(
CosmosClient cosmosDbClient,
string databaseName,
string containerName)
{
_container = cosmosDbClient.GetContainer(databaseName, containerName);
}
我想将此服务的两个不同实例传递到函数应用程序中。每个服务实例代表一个不同的容器。
如何使用 FunctionsHostBuilder 在 Startup:FunctionsApp class 中进行设置?
默认 DI 容器 does not support 命名了这样的场景,因此您有下一个选项 - 为每个 databaseName-containerName 对创建单独的接口和实现(和 register/resolve 它们)或创建一个工厂和用它来生成所需的 CosmosDbService
实例:
public interface ICosmosDbServiceFactory
{
ICosmosDbService Create(string databaseName, string containerName);
}
class CosmosDbServiceFactory : ICosmosDbServiceFactory
{
private readonly IServiceProvider _serviceProvider;
public CosmosDbServiceFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public ICosmosDbService Create(string databaseName, string containerName) => new CosmosDbService(
_serviceProvider.GetRequiredService<CosmosClient>(),
databaseName,
containerName
);
}
用适当的生命周期注册它并将它注入相应的 class 并在构造函数中使用它来解析所需的 ICosmosDbService
个实例。
你可以这样做,但我不推荐这样做。例如,在您的启动中,如果您有以下代码:
services.AddSingleton<ICosmosDbService, CosmosDbService>();
services.AddSingleton<ICosmosDbService, OtherCosmosDbService>();
两个实例都将在 Di 容器中注册。如果您有一个依赖此接口的 class,则以下构造函数将导致注入 OtherCosmosDbService:
public class SomeClass {
private readonly ICosmosDbService _service;
public SomeClass(ICosmosDbService service){
_service = service; // This would be OtherCosmosDbService
}
}
两者都会被注册,在这种情况下,最后一个注册“获胜”。如果你想同时获得两者,那么你可以将构造函数更改为:
public SomeClass(IEnumerable<ICosmosDbService> services){
// Write logic to handle finding which one you want
}
老实说,我同意 Guru Stron 的建议,即为每个容器创建单独的接口并分别注册它们。
我正在 Visual Studio 使用 c# 和 .NET 6 创建一个 Azure Function App。
我创建了一个实现接口 ICosmosDBService 的服务 (CosmosDBService):
public class CosmosDbService : ICosmosDbService
{
private Container? _container = null;
public CosmosDbService(
CosmosClient cosmosDbClient,
string databaseName,
string containerName)
{
_container = cosmosDbClient.GetContainer(databaseName, containerName);
}
我想将此服务的两个不同实例传递到函数应用程序中。每个服务实例代表一个不同的容器。
如何使用 FunctionsHostBuilder 在 Startup:FunctionsApp class 中进行设置?
默认 DI 容器 does not support 命名了这样的场景,因此您有下一个选项 - 为每个 databaseName-containerName 对创建单独的接口和实现(和 register/resolve 它们)或创建一个工厂和用它来生成所需的 CosmosDbService
实例:
public interface ICosmosDbServiceFactory
{
ICosmosDbService Create(string databaseName, string containerName);
}
class CosmosDbServiceFactory : ICosmosDbServiceFactory
{
private readonly IServiceProvider _serviceProvider;
public CosmosDbServiceFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public ICosmosDbService Create(string databaseName, string containerName) => new CosmosDbService(
_serviceProvider.GetRequiredService<CosmosClient>(),
databaseName,
containerName
);
}
用适当的生命周期注册它并将它注入相应的 class 并在构造函数中使用它来解析所需的 ICosmosDbService
个实例。
你可以这样做,但我不推荐这样做。例如,在您的启动中,如果您有以下代码:
services.AddSingleton<ICosmosDbService, CosmosDbService>();
services.AddSingleton<ICosmosDbService, OtherCosmosDbService>();
两个实例都将在 Di 容器中注册。如果您有一个依赖此接口的 class,则以下构造函数将导致注入 OtherCosmosDbService:
public class SomeClass {
private readonly ICosmosDbService _service;
public SomeClass(ICosmosDbService service){
_service = service; // This would be OtherCosmosDbService
}
}
两者都会被注册,在这种情况下,最后一个注册“获胜”。如果你想同时获得两者,那么你可以将构造函数更改为:
public SomeClass(IEnumerable<ICosmosDbService> services){
// Write logic to handle finding which one you want
}
老实说,我同意 Guru Stron 的建议,即为每个容器创建单独的接口并分别注册它们。