asp.net core 系列 12 選項 TOptions

来源:https://www.cnblogs.com/MrHSR/archive/2019/01/21/10291766.html
-Advertisement-
Play Games

一.概述 本章講的選項模式是對Configuration配置的功能擴展。 講這篇時有個專用名詞叫“選項類(TOptions)” 。該選項類作用是指:把選項類中的屬性與配置來源中的鍵關聯起來。舉個例,假設json文件有個Option1鍵,選項類中也有個叫Option1的屬性名,經過選項配置,這樣就能把 ...


一.概述

  本章講的選項模式是對Configuration配置的功能擴展。 講這篇時有個專用名詞叫“選項類(TOptions)” 。該選項類作用是指:把選項類中的屬性與配置來源中的鍵關聯起來。舉個例,假設json文件有個Option1鍵,選項類中也有個叫Option1的屬性名,經過選項配置,這樣就能把json中的鍵的值映射到選項類屬性值中。也可以理解在項目應用中,把一個json文件序列化到.net類。

 

  1.1選項介面介紹

    在官方文檔中選項介面有很多,這裡列舉了這些選項介面。所有選項介面基本都繼承了TOptions介面。

    // Used for notifications when TOptions instances change
    public interface IOptionsMonitor<out TOptions>
    {
        //
        // 摘要:
        //     Returns the current TOptions instance with the Microsoft.Extensions.Options.Options.DefaultName.
        TOptions CurrentValue { get; }
        //...
    }


    // Used to create TOptions instances
    public interface IOptionsFactory<TOptions> where TOptions : class, new()
    {
        //
        // 摘要:
        //     Returns a configured TOptions instance with the given name.
        TOptions Create(string name);
    }


    // Represents something that configures the TOptions type. Note: These are run before all 
    public interface IConfigureOptions<in TOptions> where TOptions : class
    {
        //
        // 摘要:
        //     Invoked to configure a TOptions instance.
        //
        // 參數:
        //   options:
        //     The options instance to configure.
        void Configure(TOptions options);
    }


    public interface IPostConfigureOptions<in TOptions> where TOptions : class
    {
        //
        // 摘要:
        //     Invoked to configure a TOptions instance.
        //
        // 參數:
        //   name:
        //     The name of the options instance being configured.
        //
        //   options:
        //     The options instance to configured.
        void PostConfigure(string name, TOptions options);
    }


    public interface IConfigureNamedOptions<in TOptions> : IConfigureOptions<TOptions> where TOptions : class
    {
        //
        // 摘要:
        //     Invoked to configure a TOptions instance.
        //
        // 參數:
        //   name:
        //     The name of the options instance being configured.
        //
        //   options:
        //     The options instance to configure.
        void Configure(string name, TOptions options);
    }


    // Used by IOptionsMonitor<TOptions> to cache TOptions instances.
    public interface IOptionsMonitorCache<TOptions> where TOptions : class
    {
        //
        // 摘要:
        //     Clears all options instances from the cache.
        void Clear();
        //
        // 摘要:
        //     Gets a named options instance, or adds a new instance created with createOptions.
        //
        // 參數:
        //   name:
        //     The name of the options instance.
        //
        //   createOptions:
        //     The func used to create the new instance.
        //
        // 返回結果:
        //     The options instance.
        TOptions GetOrAdd(string name, Func<TOptions> createOptions);
        //
        // 摘要:
        //     Tries to adds a new option to the cache, will return false if the name already
        //     exists.
        //
        // 參數:
        //   name:
        //     The name of the options instance.
        //
        //   options:
        //     The options instance.
        //
        // 返回結果:
        //     Whether anything was added.
        bool TryAdd(string name, TOptions options);
        //
        // 摘要:
        //     Try to remove an options instance.
        //
        // 參數:
        //   name:
        //     The name of the options instance.
        //
        // 返回結果:
        //     Whether anything was removed.
        bool TryRemove(string name);
    }


    // Used to access the value of TOptions for the lifetime of a request
    public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class, new()
    {
        //
        // 摘要:
        //     Returns a configured TOptions instance with the given name.
        TOptions Get(string name);
    }

    //Used to retrieve configured TOptions instances
    public interface IOptions<out TOptions> where TOptions : class, new()
    {
        //
        // 摘要:
        //     The default configured TOptions instance
        TOptions Value { get; }
    }
View Code

 

    (1)  IOptionsMonitor<TOptions>

      IOptionsMonitor<TOptions>用於TOptions實例更改時的通知,用於管理 TOptions選項類 。該IOptionsMonitor<TOptions>支持以下方案:

      (1) 更改通知。當配置文件發生修改時,會監聽同步到選項類。

      (2) 命名選項。IConfigureNamedOptions支持命名選項。介面繼續關係 IConfigureNamedOptions:IConfigureOptions

      (3) 重新載入配置。通過 IOptionsSnapshot 重新載入配置數據,IOptionsMonitor也支持該功能。 介面繼續關係IOptionsSnapshot :IOptions

      (4) 選擇性選項失效 (IOptionsMonitorCache<TOptions>)。

    (2)  其它介面

      IOptionsFactory<TOptions> 負責產生TOptions選項實例,它具有單個 Create 方法。

      預設實現採用所有已註冊 IConfigureOptions<TOptions> 和 IPostConfigureOptions<TOptions> 並首先運行所有配置(所有的來源配置),

      然後才進行選項後期配置IPostConfigureOptions<TOptions> 。

      IOptionsMonitorCache<TOptions>用於緩存TOptions實例。

      

  1.2 常規選項配置

    TOptions選項類必須為包含公共無參數構造函數的非抽象類。下麵示例中選項類MyOptions具有兩種屬性:Option1 和 Option2。 設置預設值為可選,但以下示例中的類構造函數設置了 Option1 的預設值。 Option2 具有通過直接初始化屬性設置的預設值。

     public class MyOptions
      {
          public MyOptions()
          {
              // Set default value.
              Option1 = "value1_from_ctor";
          }

          public string Option1 { get; set; }
          public int Option2 { get; set; } = 5;
      }
       //將MyOptions類已通過Configure添加到服務容器,並綁定到配置IConfiguration上
       //Registers a configuration instance which TOptions will bind against.
       services.Configure<MyOptions>(Configuration);
        private readonly MyOptions _options;
     //OtherPages/Page1 public Page1Model( IOptionsMonitor<MyOptions> optionsAccessor) { _options = optionsAccessor.CurrentValue; } public void OnGet() { var option1 = _options.Option1; var option2 = _options.Option2; var SimpleOptions = $"option1 = {option1}, option2 = {option2}"; }
    // 此時SimpleOptions值:"option1 = value1_from_ctor, option2 = 5"
      //下麵在appsettings.json 文件添加 option1 和 option2 的值。
        "option1": "value1_from_json",
        "option2": -1,

    當配置文件appsettings.json中option1和option2鍵的值改變後,MyOptions 選項類中的屬性option1和option2的值也會改變。 下麵再次運行OtherPages/Page1

      //此時SimpleOptions的值為:"option1 = value1_from_json, option2 = -1"

    為什麼MyOptions類中option1,option2會取到appsettings.json文件中的值呢?因為MyOptions選項類註入到Iconfiguration服務後與appsettings.json文件中鍵相同,形成了映射。

 

  1.3 通過委托配置簡單選項

     使用委托設置選項值。 此示例應用使用 MyOptionsWithDelegateConfig 類 ,這裡仍然是使用相同的鍵Option1,Option2。 它通過 MyOptionsWithDelegateConfig 使用委托來配置綁定。

      public class MyOptionsWithDelegateConfig
    {
        public MyOptionsWithDelegateConfig()
        {
            // Set default value.
            Option1 = "value1_from_ctor";
        }
    
         public string Option1 { get; set; }
         public int Option2 { get; set; } = 5;
    }
         services.Configure<MyOptions>(Configuration);
         //第二個註入服務
         services.Configure<MyOptionsWithDelegateConfig>(myOptions =>
         {
         // 在Page1Model構造方法中生成MyOptionsWithDelegateConfig實例時調用 myOptions.Option1
= "value1_configured_by_delegate"; myOptions.Option2 = 500; });

    

    public Page1Model(
            IConfiguration configuration,
            IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig,
            IOptionsMonitor<MyOptions> optionsAccessor
          )
        {
        
            _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
            _options = optionsAccessor.CurrentValue;
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        private readonly MyOptions _options;
        private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;

        public string BindGUIDMsg { get; set; }

        public void OnGet()
        {
            BindGUIDMsg = $"option1 = {_options.Option1}, option2 = {_options.Option2}";

            BindGUIDMsg += "</br>";

            BindGUIDMsg += $"delegate_option1 = {_optionsWithDelegateConfig.Option1}, " +
                           $"delegate_option2 = {_optionsWithDelegateConfig.Option2}";
        }

    每次調用 Configure 都會將 IConfigureOptions<TOptions> 服務添加到服務容器。 在前面的示例中,Option1 和 Option2 的值同時在 appsettings.json 中指定,但 Option1 和 Option2 的值被配置的委托替代。

    當啟用多個配置服務時,指定的最後一個配置源優於其他源,由其設置配置值。 運行應用時,頁面模型的 OnGet 方法返回顯示選項類值的字元串:

    // myOptions實例取值如下:
    SimpleOptions:option1 = -1,option2 = 5 
    // MyOptionsWithDelegateConfig實例取值如下:
    delegate_option1 = value1_configured_by_delegate,delegate_option2 = 500

 

   1.4 子選項配置

     當配置文件中的子節點需要與選項類進行關聯映射時,可以通過服務註入bind到指定的Configuration節點。在以下代碼中,已向服務容器添加第三個 IConfigureOptions<TOptions> 服務。 它將 MySubOptions 綁定到 appsettings.json 文件的 subsection 部分:

      "Option1": "value1_from_json",
      "Option2": -1,
      "subsection": {
         "suboption1": "subvalue1_from_json",
         "suboption2": 200
      }
     public class MySubOptions
      {
          public MySubOptions()
          {
              // Set default values.
              SubOption1 = "value1_from_ctor";
              SubOption2 = 5;
          }

          public string SubOption1 { get; set; }
          public int SubOption2 { get; set; }
      }
//第三個IConfigureOptions<TOptions>註入服務
         services.Configure<MySubOptions>(Configuration.GetSection("subsection"));
    //OtherPages/Page1              
     public Page1Model(
            IConfiguration configuration,
            IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig,
            IOptionsMonitor<MyOptions> optionsAccessor,
            IOptionsMonitor<MySubOptions> subOptionsAccessor
          )
        {
        
            _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
            _options = optionsAccessor.CurrentValue;
            _subOptions = subOptionsAccessor.CurrentValue;
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        private readonly MyOptions _options;
        private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;
        private readonly MySubOptions _subOptions;
       // OnGet方法
      SubOptions = $"subOption1 = {_subOptions.SubOption1}, subOption2 = {_subOptions.SubOption2}"
      //運行應用時,OnGet 方法返回顯示子選項類值的字元串:
      // MySubOptions實例取值如下:
      subOption1 = subvalue1_from_json,subOption2 = 200

    

  1.5 IConfigureNamedOptions選項命名

    IConfigureNamedOptions:是用於對選項類在註入服務時,進行命名。下麵是把MyOptions選項類註入到服務,並取了別名named_options_1。 如下所示:

      services.Configure<MyOptions>("named_options_1", Configuration);
    //在要使用的頁面,如下所示:
    private readonly MyOptions _named_options_1;
    public IndexModel(
        IOptionsSnapshot<MyOptions> namedOptionsAccessor)
    {
        _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    }
     // IOptionsSnapshot源碼
      public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class, new()
      {
          //
          // 摘要:
          //     Returns a configured TOptions instance with the given name.
          TOptions Get(string name);
      }

 

  1.6 ConfigureAll 

    上面介紹的選項類,在註入服務時都是使用的services.Configure,它是針對選項類的當前實例,例如:在page1和page2都使用了實例MyOptions( private readonly MyOptions _options)但它們屬於不同的實例。 

      //使用 ConfigureAll 方法配置所有選項實例
            services.ConfigureAll<MyOptions>(myOptions =>
            {
                //所有MyOptions實例配置 Option1的值
                myOptions.Option1 = "ConfigureAll replacement value";
            });
      //添加代碼後運行示例應用將產生以下結果:
      named_options_1: option1 = ConfigureAll replacement value, option2 = -1
      named_options_2: option1 = ConfigureAll replacement value, option2 = 5

 

  總結:

         選項模式是對Configuration配置的功能擴展,主要用於把json文件序列化到.net類(選項類)。通過註入services. Configure或services.ConfigureAll把選項類註入到服務並綁定到Configuration上。 選項這篇還有其它功能如:選項後期配置( IPostConfigureOptions), 啟動期間訪問選項, 選項驗證等,詳細瞭解查看官網

 

參考文獻

官方資料:asp.net core 選項


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.下載打開Consul 筆者是windows下麵開發的(也可以使用Docker)。 官網下載windows的Consul https://www.consul.io/ 使用cmd視窗打開,輸入 訪問預設127.0.0.1:8500就可以看到界面化的Consul 2.在服務端註冊 接著上一篇 app ...
  • 1.什麼是gRPC 官方文檔:https://grpc.io/docs/guides/index.html 2.什麼是MagicOnion MagicOnion開源地址:https://github.com/Cysharp/MagicOnion 3.服務端代碼 新建一個WebAPI項目 4.客戶端 ...
  • 年末將至,又到了一年一度的收集發票時間,平時零零碎碎的花錢都是不在意開發票,現在好了,到處找發票來報銷,簡直頭大, 東拼西湊,終於搞定了全部發票,大伙多餘的發票,麻煩艾特我一下啊,不限日期,能開發票的都可以,謝謝啦。文章後有彩蛋~ 這麼多的發票,一張一張列印,要浪費我多少時間,就想著合併這些PDF文 ...
  • https://www.cnblogs.com/Stephenchao/p/4481995.html 兩個現實中的例子:1、B超:大家體檢的時候大概都做過B超吧,B超可以透過肚皮探測到你內髒的生理情況。這是如何做到的呢?B超是B型超聲波,它可以透過肚皮通過向你體內發射B型超聲波,當超聲波遇到內臟壁的 ...
  • 命名空間:using System.Xml; 1、查找某個節點是否存在: 2、增加節點: 添加節點,如果有多級節點,從n級節點往上添加節點的順序添加。 3、刪除節點: 4、修改節點: https://www.cnblogs.com/guxia/p/8242483.html ...
  • 轉眼2019年,畢業也算是有10年之餘了。雖然大學不是電腦專業,畢業後也沒有從事電腦的相關工作,但心中,總是有著電腦的學習情結。以至於這麼多年來,一直斷斷續續的學一點知識,然後又迅速的忘記,如此反覆,竟樂此不疲(這其實是自欺欺人罷了)。 言歸正傳,這些年來,忙來忙去,其實做的就那麼一點東西,今 ...
  • 在本章中,將繼續介紹如何利用 EFCore 連接到 MariaDB/MySql 和 PostgreSQL 資料庫,同時,在一個項目中,如何添加多個資料庫上下文對象,併在業務中使用多個上下文對象,通過這兩章的學習,你將掌握使用 EFCore 連接 MSSQL/MariaDB/MySql/Postgre... ...
  • checkbox的html 引用bootstrap-switch的css和js 動態設置某個checkbox開關控制狀態 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...