C#程序启动时如何通过依赖注入创建多实例ElasticSearchHelper
实现多个不同配置ElasticSearchHelper实例的依赖注入方案
方案1:利用.NET键控服务(Keyed Services,.NET 6+支持)
你完全没必要新建ElasticSearchHelper_01这类重复的实现类,直接通过键控服务就能区分不同配置的实例:
- 注册两个带标识的单例服务:
// 注册第一个实例,标识为"EsInstance1" builder.Services.AddKeyedSingleton<IElasticSearchHelper>("EsInstance1", x => new ElasticSearchHelper(url_1, user, password)); // 注册第二个实例,标识为"EsInstance2" builder.Services.AddKeyedSingleton<IElasticSearchHelper>("EsInstance2", x => new ElasticSearchHelper(url_2, user, password));
- 在需要注入的类中,通过
[FromKeyedServices]指定要使用的实例:
public class MyBusinessService { private readonly IElasticSearchHelper _esHelper1; private readonly IElasticSearchHelper _esHelper2; public MyBusinessService( [FromKeyedServices("EsInstance1")] IElasticSearchHelper esHelper1, [FromKeyedServices("EsInstance2")] IElasticSearchHelper esHelper2) { _esHelper1 = esHelper1; _esHelper2 = esHelper2; } }
这种方式避免了冗余代码,适合实例数量固定且较少的场景。
方案2:实现工厂模式(适合多实例或动态创建场景)
如果后续可能需要新增更多ElasticSearch实例,或者需要动态配置实例,工厂模式的扩展性更强:
- 定义工厂接口:
public interface IElasticSearchHelperFactory { IElasticSearchHelper GetInstance(string instanceKey); }
- 实现工厂类,内部管理所有实例:
public class ElasticSearchHelperFactory : IElasticSearchHelperFactory { private readonly Dictionary<string, IElasticSearchHelper> _instanceCache; public ElasticSearchHelperFactory(string url1, string user, string password, string url2) { _instanceCache = new Dictionary<string, IElasticSearchHelper> { ["Instance1"] = new ElasticSearchHelper(url1, user, password), ["Instance2"] = new ElasticSearchHelper(url2, user, password) }; } public IElasticSearchHelper GetInstance(string instanceKey) { if (_instanceCache.TryGetValue(instanceKey, out var instance)) { return instance; } throw new ArgumentException($"未找到标识为{instanceKey}的ElasticSearch实例"); } }
- 将工厂注册为单例服务:
builder.Services.AddSingleton<IElasticSearchHelperFactory>(x => new ElasticSearchHelperFactory(url_1, user, password, url_2));
- 在业务类中通过工厂获取指定实例:
public class MyBusinessService { private readonly IElasticSearchHelper _esHelper1; private readonly IElasticSearchHelper _esHelper2; public MyBusinessService(IElasticSearchHelperFactory esFactory) { _esHelper1 = esFactory.GetInstance("Instance1"); _esHelper2 = esFactory.GetInstance("Instance2"); } }
方案对比
- 键控服务:代码简洁,无需额外类,适合实例数量固定且少的场景。
- 工厂模式:扩展性强,支持动态添加实例、配置变更,适合实例数量多或需要动态创建的场景。
内容的提问来源于stack exchange,提问作者Savitar
相关产品推荐
相关产品推荐

