如何通过依赖注入构建带Logger的多实例MyX类?
解决方法
方法一:用服务提供者委托逐个注册
不要在注册阶段直接实例化MyX,改用工厂委托让DI容器在解析阶段创建实例,此时就能正常获取ILogger<MyX>:
// 注册第一个实例 builder.Services.AddSingleton<IX>(sp => new MyX(sp.GetRequiredService<ILogger<MyX>>(), "field value 1")); // 注册第二个实例 builder.Services.AddSingleton<IX>(sp => new MyX(sp.GetRequiredService<ILogger<MyX>>(), "field value 2"));
MyService构造函数中的IEnumerable<IX>会自动包含这两个实例,每个实例都能拿到正确注入的Logger。
方法二:从配置批量注册
如果你的配置里存了多个MyX的Field值(比如appsettings.json中有对应配置节),可以循环配置项批量注册:
假设appsettings.json配置如下:
{ "xs": [ {"Field": "field value 1"}, {"Field": "field value 2"} ] }
注册代码:
// 先绑定配置到辅助类 var myXConfigs = configuration.GetSection("xs").Get<List<MyXConfig>>(); // 循环注册每个实例 foreach (var config in myXConfigs) { builder.Services.AddSingleton<IX>(sp => new MyX(sp.GetRequiredService<ILogger<MyX>>(), config.Field)); } // 用于绑定配置的辅助类 public class MyXConfig { public string Field { get; set; } }
这种方式适合配置驱动的场景,不用手动编写每个实例的注册代码。
方法三:直接注册IEnumerable工厂
如果需要更灵活的创建逻辑,可以直接注册IEnumerable<IX>,一次性创建所有实例:
builder.Services.AddSingleton<IEnumerable<IX>>(sp => { var logger = sp.GetRequiredService<ILogger<MyX>>(); var configs = configuration.GetSection("xs").Get<List<MyXConfig>>(); return configs.Select(config => new MyX(logger, config.Field)).ToList(); });
这种方式会在首次解析IEnumerable<IX>时创建所有MyX实例,同样能保证Logger被正确注入。
核心原因
之前直接new MyX(...)是在服务注册阶段执行的,此时DI容器还未完成初始化,无法获取ILogger<MyX>;而工厂委托的逻辑是在服务解析阶段执行的,此时容器已初始化完成,可以正常获取依赖服务。
内容的提问来源于stack exchange,提问作者Søren Debois
相关产品推荐
相关产品推荐

