.NET Core读取配置文件的方法
配置文件是每个项目最基础的部分,也是不可或缺的部分,比如:数据库连接、中间件属性等常见的配置。
今天这篇文章主要内容就是,在.net core项目中怎样去读取配置文件并使用。
提前准备
appsettings.json 文件
{ "user": { "username": "赵一", "userage": 18 } }
对应实体模型
public class useroption { public string username { get; set; } public int userage { get; set; } }
常规读取
1、注册
在 startup 类中注册,主要用到的是 configure 方法:
services.configure<useroption>(configuration.getsection("user"));
2、控制器中注入并读取
public class homecontroller : controllerbase { private readonly useroption user; public homecontroller(ioptions<useroption> useroptions) { user = useroptions.value; } [httpget] public string get() { return $"姓名:{user.username},年龄:{user.userage} "; } }
输出结果:姓名:赵一,年龄:18
嵌套读取
我们对 appsettings.json 文件做一点小小的改动,增加一个子节点 child
:
{ "user": { "username": "赵一", "userage": 18, "child": { "username": "赵一的崽", "userage": 2 } } }
再对注册的代码做一点小小的修改:
services.configure<useroption>(configuration.getsection("user:child"));
输出结果:姓名:赵一的崽,年龄:2
分实例读取
这个时候需求又有变化了,需要同时读取 user
与 child
节点的数据,我们试试下面的方法看可行不可行:
// 注册 services.configure<useroption>(configuration.getsection("user")); services.configure<useroption>(configuration.getsection("user:child")); // 控制器 public class homecontroller : controllerbase { private readonly useroption user; private readonly useroption child; public homecontroller(ioptions<useroption> useroptions, ioptions<useroption> childoptions) { user = useroptions.value; child = childoptions.value; } [httpget] public string get() { return $"姓名:{user.username},年龄:{user.userage} \r\n姓名:{child.username},年龄:{child.userage}"; } }
输出结果很显然满足不了我们的需求:
姓名:赵一的崽,年龄:2 姓名:赵一的崽,年龄:2
有的小伙伴肯定会说,在实体模型内在加一个子节点字段。这样肯定是没问题的,但是与常规读取方式就没什么两样了。
这里我要说的是分实例读取,引入 configure
的另一个重载方法,与之前不同的是多了一个参数 name
:
public static iservicecollection configure<toptions>(this iservicecollection services, string name, iconfiguration config) where toptions : class;
下面我们重新注册:
services.configure<useroption>("father", configuration.getsection("user")); services.configure<useroption>("son", configuration.getsection("user:child"));
在控制器构造函数中注入,也引入了一个新的接口对象:ioptionsmonitor
public class homecontroller : controllerbase { private readonly useroption user; private readonly useroption child; public homecontroller(ioptionsmonitor<useroption> useroptions, ioptionsmonitor<useroption> childoptions) { user = useroptions.get("father"); child = childoptions.get("son"); } [httpget] public string get() { return $"姓名:{user.username},年龄:{user.userage} \r\n姓名:{child.username},年龄:{child.userage}"; }
输出结果:
姓名:赵一,年龄:18 姓名:赵一的崽,年龄:2
其实还有一个接口对象能实现这样的效果:ioptionssnapshot
,那 ioptionsmonitor
与 ioptionssnapshot
有什么不同呢?请接着往下看。
ioptionsmonitor与ioptionssnapshot的不同之处
我们先来看看微软官方的注释:
ioptionsmonitor
// // 摘要: // used for notifications when toptions instances change. // // 类型参数: // toptions: // the options type. public interface ioptionsmonitor<out toptions> { // // 摘要: // returns the current toptions instance with the microsoft.extensions.options.options.defaultname. toptions currentvalue { get; } // // 摘要: // returns a configured toptions instance with the given name. toptions get(string name); // // 摘要: // registers a listener to be called whenever a named toptions changes. // // 参数: // listener: // the action to be invoked when toptions has changed. // // 返回结果: // an system.idisposable which should be disposed to stop listening for changes. idisposable onchange(action<toptions, string> listener); }
ioptionssnapshot
// // 摘要: // used to access the value of toptions for the lifetime of a request. // // 类型参数: // toptions: // options type. public interface ioptionssnapshot<out toptions> : ioptions<toptions> where toptions : class, new() { // // 摘要: // returns a configured toptions instance with the given name. toptions get(string name); }
从字面上理解,ioptionsmonitor
建议在配置信息更改后需要通知的场景下使用,所以多了个 onchange
的方法;而 ioptionssnapshot
翻译过来的意思是:用于在请求的生命周期内访问配置,有点难以理解哈,我们接下来用代码来验证一下。
ioptionsmonitor 与 ioptionssnapshot的生命周期
我们对实体模型再做一点小小的修改,增加一个 guid 字段,并给上默认值:
public class useroption { public string username { get; set; } public int userage { get; set; } public guid guid { get; set; } = guid.newguid(); }
我们再次运行程序:
father — 姓名:赵一,年龄:19,编号:e0d71f47-e8f1-4a6d-875e-2074c985f4a0 son — 姓名:赵一的崽,年龄:3,编号:d865151b-f9bf-4eff-bb4e-8ab6dc61160c
然后不停的刷新页面会发现,father
的编号没有发生任何编号,而 son
的编号每次刷新都会改变。这是不是比较像我们注册时所用到的三种模式:
services.addscoped(); services.addtransient(); services.addsingleton()
其中 father
类似 addsingleton
,son
则类似 addscoped
与 addtransient
。
大家可以在同一个方法里多次调用 childoptions.get("son")
看看 son
到底时类似 addscoped
还是 addtransient
。
ioptionsmonitor的onchange调用方式
useroptions.onchange((user,name)=> { console.writeline(user.username +"-"+ name); });
无文件配置
无文件配置就是不需要以静态文件的方式进行配置。相关信息在配置一次后就不用再做修改,我们可以采用无文件配置的方式,比如我们熟悉的 addcors
跨域配置
services.addcors(op => { op.addpolicy(corsname, set => { set.setisoriginallowed(origin => true).allowanyheader().allowanymethod().allowcredentials(); }); });
我们对之前的注册方法进行一下改动:
services.configure<useroption>(c => { c.username = "钱二"; c.userage = 60; });
控制器注入采用常规的注入方式,最终输出结果:姓名:钱二,年龄:60
分享一个源码查看网站:https://source.dot.net/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: C#泛型运作原理的深入理解