配置文件是每个项目最基础的部分,也是不可或缺的部分,比如:数据库连接、中间件属性等常见的配置。

今天这篇文章主要内容就是,在.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

分实例读取

这个时候需求又有变化了,需要同时读取 Userchild 节点的数据,我们试试下面的方法看可行不可行:

// 注册
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,那 IOptionsMonitorIOptionsSnapshot 有什么不同呢?请接着往下看。

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 类似 AddSingletonson 则类似 AddScopedAddTransient

大家可以在同一个方法里多次调用 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/

.NET Core基础篇之:配置文件读取的更多相关文章

  1. Asp.Net Core基础篇之:白话管道中间件

    在Asp.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景 ...

  2. ASP.Net Core 5.0 MVC 配置文件读取,Startup 类中ConfigureServices 方法、Configure 方法的使用

    配置文件读取 1. 新建FirstController控制器 在appsettings文件内容替换成以下代码 { "Position": { "Title": ...

  3. .NET Core基础篇之:依赖注入DependencyInjection

    依赖注入已经不是什么新鲜话题了,在.NET Framework时期就已经出现了各种依赖注入框架,比如:autofac.unity等.只是在.net core微软将它搬上了台面,不用再依赖第三方组件(那 ...

  4. .NET Core基础篇之:集成Swagger文档与自定义Swagger UI

    Swagger大家都不陌生,Swagger (OpenAPI) 是一个与编程语言无关的接口规范,用于描述项目中的 REST API.它的出现主要是节约了开发人员编写接口文档的时间,可以根据项目中的注释 ...

  5. .NET Core基础篇之:白话管道中间件

    在.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景区很远 ...

  6. springmvc基础篇—拆分配置文件

    一般来讲,在企业实际项目中通常会将配置文件设置为两个:spring-mvc.xml.beans.xml,各自管各自的内容,方便管理. 一.在src下增加如下配置文件: <?xml version ...

  7. 【Spark机器学习速成宝典】基础篇03数据读取与保存(Python版)

    目录 保存为文本文件:saveAsTextFile 保存为json:saveAsTextFile 保存为SequenceFile:saveAsSequenceFile 读取hive 保存为文本文件:s ...

  8. .net core +codefirst(.net core 基础入门,适合这方面的小白阅读) 【我们一起写框架】领域驱动设计的CodeFirst框架(一)—序篇

    .net core +codefirst(.net core 基础入门,适合这方面的小白阅读)   前言 .net core mvc和 .net mvc开发很相似,比如 视图-模型-控制器结构.所以. ...

  9. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

随机推荐

  1. 从零入门 Serverless | 一文搞懂函数计算及其工作原理

    作者 | 孔德慧(夏莞) 阿里云函数计算开发工程师 什么是函数计算 大家都了解,Serverless 并不是没有服务器,而是开发者不再需要关心服务器.下图是一个应用从开发到上线的对比图: 在传统 Se ...

  2. 6岁!是时候重新认识下Serverless了

    一.背景 Serverless 概念从2012年开始提出,真正推出相关云产品是2014年AWS推出Lambda.如果我们将 Serverless 比作一个婴儿,那么它已经6岁了. 虽然业界对Serve ...

  3. dev分支和release是什么

    master(主分支) 存在一条主分支(master).所有用户可见的正式版本,都从master发布(也是用于部署生产环境的分支,确保master分支稳定性).主分支作为稳定的唯一代码库,不做任何开发 ...

  4. 2021.3.3--vj补题

    题目 C - C CodeForces - 1166C The legend of the foundation of Vectorland talks of two integers xx and  ...

  5. Pytorch——张量 Tensors

    张量 Tensors 1.torch.is_tensor torch.is_tensor(obj) 用法:判断是否为张量,如果是 pytorch 张量,则返回 True. 参数:obj (Object ...

  6. Python爬虫:给我一个链接,快手视频随便下载

    前言 讲一下,文明爬虫,从我做起(1.文章中的程序代码仅供学习,切莫用于商业活动,一经被相关人员发现,本小编概不负责!2.请在服务器闲时运行本程序代码,以免对服务器造成很大的负担.) 1. 实现原理 ...

  7. OO_JAVA_表达式求导_单元总结

    OO_JAVA_表达式求导_单元总结 这里引用个链接,是我写的另一份博客,讲的是设计层面的问题,下面主要是对自己代码的单元总结. 程序分析 (1)基于度量来分析自己的程序结构 第一次作业 程序结构大致 ...

  8. 使用logstash的grok插件解析springboot日志

    使用logstash的grok插件解析springboot日志 一.背景 二.解决思路 三.前置知识 四.实现步骤 1.准备测试数据 2.编写`grok`表达式 3.编写 logstash pipel ...

  9. Linux Shell Here Document

    Here Document 是一种有特殊用处的代码块,他使用IO重定向的形式记录了一段临时的文本或交互命令,并且把这些文本或命令 依次的传递给一个程序或一个命令,作为他运行时的标准输入. Here d ...

  10. DeWeb 与 Unigui的区别

    DeWeb 与 Unigui 相同: 都是采用Delphi开发网页的平台 不同: 1 DeWeb不需要安装控件, 而Unigui需要安装自己的控件 2 DeWeb无需要学习HTML/CSS/JavaS ...