如何使用依赖注入 (.NET 8) 注入两个 MongoDB 客户端?我有一个场景,我需要从 Db1/collection1 读取内容,然后将某些内容保存到 Db2/collection2。在我的启动中,我有以下内容,但不确定如何注入第二个
IMongoClient
(两者都有不同的连接字符串。)
services.AddSingleton<IMongoClient>x => new
MongoClient(My_Server_Connection1));
services.AddSingleton<IMongoClient>x => new
MongoClient(My_Server_Connection2));
我希望能够在我的 DataStore 构造函数中执行类似的操作。
数据库数据存储1:
public DataStore1(IMongoClient clientWithConStr1, IMongoClient clientWithConStr2)
{
database1 = clientWithConStr1.GetDatabase(DatabaseName1);
database2 = clientWithConStr2.GetDatabase(DatabaseName1);
}
对于要处理具有不同连接字符串的多个
MongoClient
的场景,最好实现一个工厂来按类型选择 MongoClient (提供者)。
MongoClient
。public interface IMongoClientProvider
{
public int Type { get; }
public IMongoClient GetMongoClient();
}
public class MongoClientProvider : IMongoClientProvider
{
public int Type { get; init; }
private readonly IMongoClient _client;
public MongoClientProvider(int type, string connectionString)
{
Type = type;
_client = new MongoClient(connectionString);
}
public IMongoClient GetMongoClient()
{
return _client;
}
}
MongoClientProvider
`。using System.Collections.Generic;
using System.Linq;
public class MongoClientFactory
{
private readonly IEnumerable<IMongoClientProvider> _providers;
public MongoClientFactory(IEnumerable<IMongoClientProvider> providers)
{
_providers = providers;
}
public MongoClient GetMongoClient(int type)
{
var provider = _providers.SingleOrDefault(x => x.Type == type);
if (provider == null)
{
throw new Exception("Unsupported type for provider.");
}
return provider.GetMongoClient();
}
}
MongoClientProvider
和MongoClientFactory
注册到DI容器中。services.AddSingleton<IMongoClientProvider>(new MongoClientProvider(1, My_Server_Connection));
services.AddSingleton<IMongoClientProvider>(new MongoClientProvider(2, My_Server_Connection2));
services.AddSingleton<MongoClientFactory>();
DataStore
类中,从 DI 获取 MongoClientFactory
并通过 MongoClient
检索 type
实例。public class DataStore1
{
private readonly IMongoDatabase database;
private readonly string databaseName = "DatabaseName1";
public DataStore1(MongoClientFactory factory)
{
var client = factory.GetMongoClient(1);
database = client.GetDatabase(databaseName);
}
}
public class DataStore2
{
private readonly IMongoDatabase database;
private readonly string databaseName = "DatabaseName2";
public DataStore2(MongoClientFactory factory)
{
var client = factory.GetMongoClient(2);
database = client.GetDatabase(databaseName);
}
}
您可以通过 密钥服务注册(随 .NET 8 发布的一项新功能)轻松实现此目的。
这允许您注册服务并提供密钥。您还可以指定要将实例注入到的位置的键。这样,您就不必创建标记接口,而只需依赖 .NET 依赖注入即可。
以下示例将两个
MongoClient
实例注册为单例,一个实例的键为 "MongoClientA",另一个实例的键为 "MongoClientB"。此示例仅设置不同的应用程序名称以表明实例已正确注入;在生产代码中,您可能会从配置中读取不同的连接字符串。
两个实例都被注入到
Datastore
实例中;使用 FromKeyedServices
属性允许 IoC 容器区分注册:
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
var prov = new ServiceCollection()
.AddKeyedSingleton<IMongoClient>(
Constants.MongoClientA,
(prov, key) =>
{
var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017");
settings.ApplicationName = "A";
return new MongoClient(settings);
})
.AddKeyedSingleton<IMongoClient>(
Constants.MongoClientB,
(prov, key) =>
{
var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017");
settings.ApplicationName = "B";
return new MongoClient(settings);
})
.AddSingleton<DataStore>()
.BuildServiceProvider();
var ds = prov.GetRequiredService<DataStore>();
public class Constants
{
public const string MongoClientA = "MongoClientA";
public const string MongoClientB = "MongoClientB";
}
public class DataStore
{
private readonly IMongoClient _clientA;
private readonly IMongoClient _clientB;
public DataStore(
[FromKeyedServices(Constants.MongoClientA)] IMongoClient clientA,
[FromKeyedServices(Constants.MongoClientB)] IMongoClient clientB)
{
_clientA = clientA;
_clientB = clientB;
Console.WriteLine("ApplicationName A = " + clientA.Settings.ApplicationName);
Console.WriteLine("ApplicationName B = " + clientB.Settings.ApplicationName);
}
}
运行示例时,以下文本将写入控制台:
应用程序名称 A = A
应用程序名称 B = B