如何通过依赖注入创建并配置同一类的多个实例?
问题描述
我曾查阅过类似问题及教程,但仍未掌握如何通过依赖注入创建并配置同一类的多个实例。
具体示例代码
容器代码
public class App() { public IHost Host { get; } public App() { Host = Microsoft.Extensions.Hosting.Host. CreateDefaultBuilder(). ConfigureServices((context, services) => { services.AddSingleton<ITemperatureSensor, AcmeTemperatureSensor>(); services.AddSingleton<IAcmeMachine, AcmeMachine>(); services.Configure<TemperatureSensorOptions>(context.Configuration.GetSection(nameof(TemperatureSensorOptions))); }). Build(); } }
Acme机器代码(需注入温度传感器)
public class AcmeMachine() { public AcmeMachine( Something? ) { // 如何注入温度传感器? } ITemperatureSensor WaterSensor ITemperatureSensor AirSensor }
温度传感器代码
public interface ITemperatureSensor { string SerialNumber; double GetTemperature(); } public class AcmeTemperatureSensor() { public string SerialNumber { get; } public AcmeTemperatureSensor(IOptions<TemperatureSensorOptions> options) { SerialNumber = options.Value.SerialNumber; } public double GetTemperature() { return 25.0; } }
配置文件(appsettings.json)
{ "WaterSensor": { "TemperatureSensorOptions": { "SerialNumber": "123" } }, "AirSensor": { "TemperatureSensorOptions": { "SerialNumber": "456" } } }
解决方案
1. 拆分配置绑定
针对配置文件中WaterSensor和AirSensor两个独立节点,分别绑定对应的配置选项,替代原有的单一配置绑定:
services.Configure<TemperatureSensorOptions>("WaterSensor", context.Configuration.GetSection("WaterSensor:TemperatureSensorOptions")); services.Configure<TemperatureSensorOptions>("AirSensor", context.Configuration.GetSection("AirSensor:TemperatureSensorOptions"));
2. 注册多个传感器实例
通过工厂方法分别创建绑定不同配置的传感器实例,替代原有的单一实例注册:
// 注册WaterSensor实例 services.AddSingleton<ITemperatureSensor>(sp => { var options = sp.GetRequiredService<IOptionsSnapshot<TemperatureSensorOptions>>(); var waterSensorOptions = options.Get("WaterSensor"); return new AcmeTemperatureSensor(Options.Create(waterSensorOptions)); }); // 注册AirSensor实例 services.AddSingleton<ITemperatureSensor>(sp => { var options = sp.GetRequiredService<IOptionsSnapshot<TemperatureSensorOptions>>(); var airSensorOptions = options.Get("AirSensor"); return new AcmeTemperatureSensor(Options.Create(airSensorOptions)); });
3. 修改AcmeMachine构造注入
注入IEnumerable<ITemperatureSensor>获取所有传感器实例,再通过SerialNumber筛选出对应传感器:
public class AcmeMachine { public ITemperatureSensor WaterSensor { get; } public ITemperatureSensor AirSensor { get; } public AcmeMachine(IEnumerable<ITemperatureSensor> sensors) { WaterSensor = sensors.First(s => s.SerialNumber == "123"); AirSensor = sensors.First(s => s.SerialNumber == "456"); } }
4. 确认配置类定义
确保TemperatureSensorOptions类结构与配置匹配:
public class TemperatureSensorOptions { public string SerialNumber { get; set; } = string.Empty; }
内容的提问来源于stack exchange,提问作者JasonC
相关产品推荐
相关产品推荐

