ASP.NET Core 选项模式源码学习Options Configure(一)
前言
asp.net core 后我们的配置变得更加轻量级了,在asp.net core中,配置模型得到了显著的扩展和增强,应用程序配置可以存储在多环境变量配置中,appsettings.json用户机密等 并可以通过应用程序中的相同界面轻松访问,除此之外,asp.net中的新配置系统允许使用options的强类型设置。
强类型options
在asp.net core中没有appsettings["key"]默认方法,那么推荐的是创建强类型的配置类,去绑定配置项。
public class myoptions { public string name { get; set; } public string url { get; set; } }
然后我们在appsettings.json中添加如下内容:
{ "myoptions": { "name": "testname", "url": "testurl" } }
配置绑定到类
configureservices方法进行配置以绑定到类
public void configureservices(iservicecollection services) { services.configure<myoptions>(configuration.getsection("myoptions")); services.addcontrollers(); }
myoptions只需将ioptions<>类的实例注入控制器中,然后通过value属性获取myoptions:
public class weatherforecastcontroller : controllerbase { private readonly myoptions _options; public weatherforecastcontroller(ioptions<myoptions> options) { _options = options.value; } [httpget] public okobjectresult get() { return ok(string.format("name:{0},url:{1}", _options.name,_options.url)); } }
configure
委托配置
//基础注册方式 services.configure<myoptions>(o => { o.url = "myoptions"; o.name = "name111"; }); //指定具体名称 services.configure<myoptions>("option", o => { o.url = "myoptions"; o.name = "name111"; }) ; //配置所有实例 services.configureall<myoptions>(options =>{ options.name = "name1"; options.url = "url1";});
通过配置文件配置
// 使用配置文件来注册实例 services.configure<myoptions>(configuration.getsection("myoptions")); // 指定具体名称 services.configure<myoptions>("option", configuration.getsection("myoptions"));
postconfigure
postconfigure会在configure注册完之后再进行注册
services.postconfigure<myoptions>(o => o.name = "name1"); services.postconfigure<myoptions>("option", o => o.name = "name1"); services.postconfigureall<myoptions>(o => o.name = "name1");
源码解析
iconfigureoptions接口
public interface iconfigureoptions<in toptions> where toptions : class { void configure(toptions options); }
configure为方便使用iconfigureoptions注册单例configurenamedoptions
public static iservicecollection configure<toptions>(this iservicecollection services, string name, action<toptions> configureoptions) where toptions : class { if (services == null) { throw new argumentnullexception(nameof(services)); } if (configureoptions == null) { throw new argumentnullexception(nameof(configureoptions)); } services.addoptions(); services.addsingleton<iconfigureoptions<toptions>>(new configurenamedoptions<toptions>(name, configureoptions)); return services; }
上面代码iconfigureoptions实现了configurenamedoptions,那我们再来看看内部源码
configurenamedoptions 其实就是把我们注册的action包装成统一的configure方法,以方便后续创建options实例时,进行初始化。
public class configurenamedoptions<toptions> : iconfigurenamedoptions<toptions> where toptions : class { public configurenamedoptions(string name, action<toptions> action) { name = name; action = action; } public string name { get; } public action<toptions> action { get; } public virtual void configure(string name, toptions options) { if (options == null) { throw new argumentnullexception(nameof(options)); } // null name is used to configure all named options. if (name == null || name == name) { action?.invoke(options); } } public void configure(toptions options) => configure(options.defaultname, options); }
在 services.configure
public virtual void configure(string name, toptions options) { if (options == null) { throw new argumentnullexception(nameof(options)); } // null name is used to configure all named options. if (name == null || name == name) { action?.invoke(options); } } public void configure(toptions options) => configure(options.defaultname, options);
默认使用的是options.defaultname
addoptions默认方法默认为我们注册了一些核心的类
public static iservicecollection addoptions(this iservicecollection services) { if (services == null) { throw new argumentnullexception(nameof(services)); } services.tryadd(servicedescriptor.singleton(typeof(ioptions<>), typeof(optionsmanager<>))); services.tryadd(servicedescriptor.scoped(typeof(ioptionssnapshot<>), typeof(optionsmanager<>))); services.tryadd(servicedescriptor.singleton(typeof(ioptionsmonitor<>), typeof(optionsmonitor<>))); services.tryadd(servicedescriptor.transient(typeof(ioptionsfactory<>), typeof(optionsfactory<>))); services.tryadd(servicedescriptor.singleton(typeof(ioptionsmonitorcache<>), typeof(optionscache<>))); return services; }
上一篇: 老师,有病趁早治……
推荐阅读
-
ASP.NET Core 选项模式源码学习Options IOptions(二)
-
ASP.NET Core 选项模式源码学习Options IOptionsMonitor(三)
-
ASP.NET Core 选项模式源码学习Options Configure(一)
-
(13)ASP.NET Core 中的选项模式(Options)
-
ASP.NET Core 选项模式源码学习Options IOptions(二)
-
ASP.NET Core 选项模式源码学习Options IOptionsMonitor(三)
-
ASP.NET Core 选项模式源码学习Options Configure(一)
-
(13)ASP.NET Core 中的选项模式(Options)