asp.net core 3.0 选项模式1:使用

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

一、之前的方式

之前咱们使用web.config/app.config时是这样使用配置的java

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

 

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

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"); }
  }
}

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

 

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

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


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

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

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

2.一、定义选项类

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

 

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

但更常见的方式是使用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.三、使用选项对象

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

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

网上有些文章说IOptionsMonitorCache<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了,能够尝试修改配置文件后观察变化
其它两个接口用法相似,不在叙述

三、总结

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

IOptionsMonitorCache<TOptions>

相关文章
相关标签/搜索