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


    本篇只是从应用角度来说明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选项框架原理

  • 相关阅读:
    Python环境搭建
    appium的android端的环境搭建(Window)
    Unittest中常用的十四种断言方法
    Leetcode-141(判断链表是否存在环)
    Leetcode-88(归并两个有序数组)
    Leetcode-680(回文字符串)
    Leetcode-345(反转字符串中的元音字符)
    Leetcode-633 (两数平方和)
    Leetcode-167(有序数组的 Two Sum)
    判断是否为小数
  • 原文地址:https://www.cnblogs.com/jionsoft/p/11892525.html
Copyright © 2020-2023  润新知