.net DI + option 强类型管理config
选项方式读取配置 推荐使用选项方式读取,和DI结合更好,且更好利用"reloadonchange”机制。
NuGet安装:Microsoft.Extensions.Options、Microsoft.Extensions.Configuration.Binder,当然也需要Microsoft.Extensions.Configuration、Microsoft.Extensions.Configuration.Json。
读取配置的时候,DI要声明IOptions、IOptionsMonitor、IOptionsSnapshot等类型。lOptions不会读取到新的值; 和IOptionsMonitor相比,IOptionsSnapshot会在同一个范围内(比如ASP.NET Core一个请求中) 保持一致。
建议IOptionsSnapshot。 在读取配置的地方,用IOptionsSnapshot注入 不要在构造函数里直接读取IOptionsSnapshot.Value, 是到用到的地方再读取,否则就无法更新变化。
代码
{ "total": 1100, "num": 10, "teacher": {"address": "芜湖","name":"ssr","age": 18} }
public class Config { public int Total { get; set; } public int Num { get; set; } public Teacher? Teacher { get; set; } }
public class Teacher { public int Age { get; set; } public string? Address { get; set; } public string? Name { get; set; } }
public class TestConfig { /// <summary> /// 声明一个snapshot字段 /// </summary> private readonly IOptionsSnapshot<Config> snapshot; /// <summary> /// 使用构造器方式进行注入值 /// </summary> /// <param name="snapshot"></param> public TestConfig(IOptionsSnapshot<Config> snapshot) { this.snapshot = snapshot; } /// <summary> /// 读取值 /// </summary> public void Test() { var config= snapshot.Value; Console.WriteLine($"config.Num={config.Num},config.Teacher.Name={config.Teacher.Name}"); } }
public class TestTeacher { /// <summary> /// 声明一个snapshot字段 /// </summary> private readonly IOptionsSnapshot<Teacher> snapshot; /// <summary> /// 使用构造器方式进行注入值 /// </summary> /// <param name="snapshot"></param> public TestTeacher(IOptionsSnapshot<Teacher> snapshot) { this.snapshot = snapshot; } /// <summary> /// 读取值 /// </summary> public void Test() { var teacher = snapshot.Value; Console.WriteLine($"teacher.Name={teacher.Name}"); } }
//创建ServiceCollection对象用来创建容器对象 ServiceCollection services = new ServiceCollection(); /*添加要管理的类*/ services.AddScoped<TestConfig>(); services.AddScoped<TestTeacher>(); //添加AddOptions,让DI来管理Options var options= services.AddOptions(); /*读取配置*/ ConfigurationBuilder builder =new ConfigurationBuilder(); builder.AddJsonFile("config.json",optional:false,reloadOnChange:true); IConfigurationRoot configRoot= builder.Build(); /*绑定类*/ //将json文件中的属性和config对象中的属性进行绑定 options.Configure<Config>(e => configRoot.Bind(e)) //将json文件中的teacher对象和teacher中的对象进行绑定 .Configure<Teacher>(e=>configRoot.GetSection("teacher").Bind(e)); //创建容器对象 using (ServiceProvider provider= services.BuildServiceProvider()) { //从容器中获取TestConfig对象 var testConfig = provider.GetRequiredService<TestConfig>(); var testTeacher = provider.GetRequiredService<TestTeacher>(); //调用方法 testConfig.Test(); testTeacher.Test(); }