本篇只是从应用角度来说明asp.net core的选项模式,下一篇会从源码来分析

1、以前的方式

以前我们使用web.config/app.config时是这样使用配置的

var count = ConfigurationManager.AppSettings["key"];

写["key"]操作麻烦,弱类型的还得自己转,后来有人做了封装

public static class ConfigHelper{
  public static T Get<T>(string key){
    return (T)ConfigurationManager.AppSettings[key];
  }
}

稍微好了点,全能方式,系统任何地方都可以调用,但是没有组织,最好是为单独的模块定义一个类,比如为订单模块定义一个配置类

public static class OrderConfig{
  public static int Opt1{
    get{ return ConfigHelper.Get<int>("opt1"); }
  }
}

这时我们在订单业务中随时都可以访问这个配置,且是强类型的

2、asp.net core中的选项模式

asp.net core中把这种为小模块定义的配置类称为选项模式,我们把这个配置对象称为选项对象.微软为我们定义了一些类,这些类相互协作完成了以下任务:
1、配置来源可以是内存数据、xml、json、ini文件、数据库...或其它,也要支持我们自定义的来源
2、配置文件发生更改后配置对象自动更新
3、我们希望自己控制配置的生命周期,比如:
  我希望拿到的这个选项对象在应用程序运行期间永远不变
  我希望每次请求拿到的选项对象都是最新的,意思说每次请求你都帮我根据配置源重新创建一个选项对象
  我希望首先根据源创建选项对象,并且一直缓存它,当源有变化时帮我刷新配置对象

先做个说明:可能你有了解过asp.net core中的配置,其实选项与配置没有必然的联系,因为选项模式的根本是体现为单独的模块定义一个配置对象,方便访问,至于这个配置对象的数据从哪来则不规定,你可以使用任何方式,但是使用asp.net core提供的配置功能更方便也更常见而已

再者选项模式跟依赖注入也没有必然的联系,原因跟上面一样,但是asp.net core提供的选项模式是建立在依赖注入基础上的。但又与我们通常理解的有所不同。通常我们是定义接口IA,实现类A,然后注册iocContainer.Register<IA,A>(); 然后在使用时通过构造函数或属性注入。所以你可能会认为我们为某个模块定义选项时需要定义一个选项类,再定义一个对应的什么接口。其实不需要,因为asp.net core为我们提供了相应的泛型类,具体的看下面部分的说明来理解

下面我们假设我们在做一个类似网盘的功能模块,它涉及到一些配置,允许上传的文件后缀列表、单次上传允许的文件的大小

2.1、定义选项类

public class CloudDiskOption{
  public string AllowFileTypes{ get; set; }
  public int AllowSize { get; set; }
}

2.2、定义选项对象如何赋值

asp.net core允许我们自己来定义选项对象如何赋值,最简单的方式是使用委托,代码如下

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CloudDiskOption>(c=> {
   c.AllowSize = 1024;
  c.AllowFileTypes = "jpg,zip,pdf,docx";
  });
   services.AddControllersWithViews();
}

这样将来我们在需要使用选项类时asp.net core的选项框架会使用这个委托来帮我们创建

但更常见的方式是使用asp.net core提供的配置
西安在appsettings.json中做如下配置:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"myoption": {
"allowFileTypes": "jpg,zip,pdf,docx",
"allowSize": "1024"
}
}

你会看到我故意将选项类名与这里的配置键myoption设置成不一样,且配置项的大小写也不对应,这些属于配置部分的内容,这里不多讲,下面修改我们的Startup类

public void ConfigureServices(IServiceCollection services)
{
services.Configure<CloudDiskOption>(Configuration.GetSection("myoption"));
services.AddControllersWithViews();
}

这样将来我们需要选项对象时系统会通过配置来创建选项对象

2.3、使用选项对象

通常我们使用以来注入来获取选项对象,asp.net core为我们提供了几个泛型接口,个人理解的基本原则如下

  • 当你的选项对象基本不变时使用IOptions<TOptions> ,它会一直缓存选项对象,可以理解为单例选项对象
  • 当你希望每个请求都重读配置以获得新的选项对象时使用IOptionsSnapshot<TOptions>
  • 当你希望一直缓存我的选项对象,但当配置源发生更改时自动更新我的选项对象时使用IOptionsMonitor<TOptions>

网上有些文章说IOptionsMonitor<TOptions>是使用得最少的,我反而觉得它应该是最常用的
另外它有个OnChange可以注册一个委托,就是当选项更改后你希望做啥,看情况应该小心使用,因为它可能会导致你的调用方的对象一直无法释放,但是我想微软不会太傻,应该有个释放机制,目前那里的源码没看太懂

下面我们来看咋用,比如我们希望在controller中访问选项,通过构造函数注入

public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
CloudDiskOption myOption;
public HomeController(ILogger<HomeController> logger, IOptionsMonitor<CloudDiskOption> optionsMonitor)
{
_logger = logger;
optionsMonitor.OnChange((a,b)=>
{
//危险
});
this.myOption = optionsMonitor.CurrentValue;
}

这是你的controller对象的其他action就可以随便访问myOption了,可以尝试修改配置文件后观察变化
其它两个接口用法类似,不在叙述

3、总结

从应用的角度来讲选项用起来还是非常简单方便的,两个步骤:1定义选项的如何赋值 2使用的地方通过相应的泛型接口注入
下一篇会从源码来分析asp.net core选项框架原理

asp.net core 3.0 选项模式1:使用的更多相关文章

  1. (13)ASP.NET Core 中的选项模式(Options)

    1.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对 ...

  2. ASP.NET Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...

  3. ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介

    概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...

  4. .Net Core 2.0生态(3):ASP.NET Core 2.0 特性介绍和使用指南

    ASP.NET Core 2.0 发布日期:2017年8月14日 ASP.NET团队宣布ASP.NET Core 2.0正式发布,发布Visual Studio 2017 15.3支持ASP.NET ...

  5. ASP.NET Core 2.0 : 三. 项目结构

    本章我们一起来对比着ASP.NET Framework版本看一下ASP.NET Core 2.0的项目结构.(此后的文章也尽量这样对比着, 方便学习理解.) 关注差异, 也为项目迁移做准备. 新建项目 ...

  6. ASP.NET Core 1.0基础之依赖注入

      来源https://docs.asp.net/en/latest/fundamentals/dependency-injection.html ASP.NET Core 1.0在设计上原生就支持和 ...

  7. ASP.NET Core 1.0: Using Entity Framework Core

    伴随着ASP.NET Core 1.0发布的还有Entity Framework Core 1.0; 官方文档链接:https://docs.efproject.net/en/latest/platf ...

  8. 【翻译】asp.net core 3.0基本概念

    这篇文章描述了开发asp.net core所需要掌握的基本概念. 原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/?vie ...

  9. 避免在ASP.NET Core 3.0中为启动类注入服务

    本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库 Part 2 - IHostingE ...

随机推荐

  1. 部署 kube-controller-manager 高可用集群

    目录 前言 创建kube-controller-manager证书和私钥 生成证书和私钥 将生成的证书和私钥分发到所有master节点 创建和分发kubeconfig文件 分发kubeconfig到所 ...

  2. 如何解决jpa 要求column 名称单词必须用下划线

    [转]:http://www.jeesns.cn/article/detail/6657 先引出轮子http://blog.csdn.net/54powerman/article/details/76 ...

  3. 关于Python中的错误与异常,你是否了解的够仔细?

    每次版本结束都描述这着同样的错误,相似的问题,但始终没见解决.所以今天,我就来总结下Python的错误与异常! 异常与错误 错误 语法错误 可以通过IDE或者解释器给出提示的错误 opentxt('a ...

  4. 基于webpack实现多html页面开发框架三 图片等文件路径替换、并输出到打包目录

    一.解决什么问题      1.图片路径替换.并输出到打包目录      2.输出目录清理 二.需要安装的包 file-loader:html.css中图片路径替换,图片输出到打包目录:命令:npm ...

  5. MySql CPU彪高到百分之1000的排查思路

    You need to enable JavaScript to run this app.   原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等情况,可查看当前链接:https:// ...

  6. iOS FMDatabase 本地数据库的创建和几个基本使用方法

    转自:http://blog.it985.com/3677.html 使用数据库之前当然要先在网上下载FMDB的库,然后添加到自己的工程里面去.没有的请点击下面的来下载 fmdb 在FrameWork ...

  7. JavaScript基础3

    While循环 在指定条件为真时循环执行代码块.先确定条件再执行代码 语法 while(条件) { 需要执行的代码 } 条件中所用变量如果没有值,循环就不会停下,会导致浏览器崩溃: do...whil ...

  8. Python元组tuple(不可变)

    Python元组Tuple(不可变): 元组的特点: 1.元组的初始化: tuple = (1, )  #元组只有一个元素的话,初始化时要加,否则当做元素的普通变量类型处理 tuple = (1, 2 ...

  9. Orleans[NET Core 3.1] 学习笔记(一).NET环境下的分布式应用程序

    前言 Orleans是一个跨平台的框架,用于搭建可扩展的分布式应用程序 第一次接触Orleans还是两年前做游戏服务器的时候,用SignalR+Orleans的组合,写起代码来不要太爽. 即将进入20 ...

  10. 自建邮件服务器域名解析设置(A与MX记录)

    自建邮件服务器域名解析设置(A与MX记录) 前言 如果域名没有做解析,只能用于内网收发邮件.要想实现与外网邮箱的收发,需要做域名解析.是在"域名解析后台"进行设置(域名提供商提供& ...