ASP.NET Core 選項模式源碼學習Options Configure(一)

来源:https://www.cnblogs.com/yyfh/archive/2019/12/11/12020522.html

前言 ASP.NET Core 後我們的配置變得更加輕量級了,在ASP.NET Core中,配置模型得到了顯著的擴展和增強,應用程式配置可以存儲在多環境變數配置中,appsettings.json用戶機密等 並可以通過應用程式中的相同界面輕鬆訪問,除此之外,ASP.NET中的新配置系統允許使用Opt ...


前言

ASP.NET Core 後我們的配置變得更加輕量級了,在ASP.NET Core中,配置模型得到了顯著的擴展和增強,應用程式配置可以存儲在多環境變數配置中,appsettings.json用戶機密等 並可以通過應用程式中的相同界面輕鬆訪問,除此之外,ASP.NET中的新配置系統允許使用Options的強類型設置。

強類型Options

在ASP.NET Core中沒有AppSettings["Key"]預設方法,那麼推薦的是創建強類型的配置類,去綁定配置項。


    public class MyOptions
    {
        public string Name { get; set; }

        public string Url { get; set; }
    }

然後我們在appsettings.json中添加如下內容:


{
  "MyOptions": 
    {
      "Name": "TestName",
      "Url": "TestUrl"
    }
}

配置綁定到類

ConfigureServices方法進行配置以綁定到類

        public void ConfigureServices(IServiceCollection services)
        {

            services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
            services.AddControllers();

        }

MyOptions只需將IOptions<>類的實例註入控制器中,然後通過Value屬性獲取Myoptions:


    public class WeatherForecastController : ControllerBase
    {
        private readonly MyOptions _options;
        public WeatherForecastController(IOptions<MyOptions> options)
        {
            _options = options.Value;
        }

        [HttpGet]
        public OkObjectResult Get() {
            return Ok(string.Format("Name:{0},Url:{1}", _options.Name,_options.Url));
        }
    }

Configure

委托配置

            //基礎註冊方式
            services.Configure<MyOptions>(o => { o.Url = "MyOptions"; o.Name = "Name111"; });
            //指定具體名稱
            services.Configure<MyOptions>("Option", o => { o.Url = "MyOptions"; o.Name = "Name111"; }) ;
            //配置所有實例
            services.ConfigureAll<MyOptions>(options =>{ options.Name = "Name1";  options.Url = "Url1";});

通過配置文件配置

           // 使用配置文件來註冊實例
            services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
            // 指定具體名稱
            services.Configure<MyOptions>("Option", Configuration.GetSection("MyOptions"));
PostConfigure

PostConfigure會在Configure註冊完之後再進行註冊


     services.PostConfigure<MyOptions>(o => o.Name = "Name1");
            services.PostConfigure<MyOptions>("Option", o => o.Name = "Name1");
            services.PostConfigureAll<MyOptions>(o => o.Name = "Name1");

源碼解析

IConfigureOptions介面


    public interface IConfigureOptions<in TOptions> where TOptions : class
    {
        
        void Configure(TOptions options);
    }

Configure為方便使用IConfigureOptions註冊單例ConfigureNamedOptions


     public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, Action<TOptions> configureOptions)
            where TOptions : class
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (configureOptions == null)
            {
                throw new ArgumentNullException(nameof(configureOptions));
            }

            services.AddOptions();
            services.AddSingleton<IConfigureOptions<TOptions>>(new ConfigureNamedOptions<TOptions>(name, configureOptions));
            return services;
        }


上面代碼IConfigureOptions實現了ConfigureNamedOptions,那我們再來看看內部源碼
ConfigureNamedOptions 其實就是把我們註冊的Action包裝成統一的Configure方法,以方便後續創建Options實例時,進行初始化。


    public class ConfigureNamedOptions<TOptions> : IConfigureNamedOptions<TOptions> where TOptions : class
    {
        
        public ConfigureNamedOptions(string name, Action<TOptions> action)
        {
            Name = name;
            Action = action;
        }

       
        public string Name { get; }

      
        public Action<TOptions> Action { get; }

      
        public virtual void Configure(string name, TOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // Null name is used to configure all named options.
            if (Name == null || name == Name)
            {
                Action?.Invoke(options);
            }
        }
        public void Configure(TOptions options) => Configure(Options.DefaultName, options);
    }

services.Configure(Configuration.GetSection("MyOptions")); 我們不指定具體名稱的時候預設是如下代碼片段


        public virtual void Configure(string name, TOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // Null name is used to configure all named options.
            if (Name == null || name == Name)
            {
                Action?.Invoke(options);
            }
        }
        public void Configure(TOptions options) => Configure(Options.DefaultName, options);

預設使用的是Options.DefaultName

AddOptions預設方法預設為我們註冊了一些核心的類


     public static IServiceCollection AddOptions(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
            services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
            services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>)));
            services.TryAdd(ServiceDescriptor.Transient(typeof(IOptionsFactory<>), typeof(OptionsFactory<>)));
            services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>)));
            return services;
        }
        

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

更多相關文章
一周排行
  • 比如要拆分“呵呵呵90909086676喝喝999”,下麵當type=0返回的是中文字元串“呵呵呵,喝喝”,type=1返回的是數字字元串“90909086676,999”, private string GetStrings(string str,int type=0) { IList<strin ...
  • Swagger一個優秀的Api介面文檔生成工具。Swagger可以可以動態生成Api介面文檔,有效的降低前後端人員關於Api介面的溝通成本,促進項目高效開發。 1、使用NuGet安裝最新的包:Swashbuckle.AspNetCore。 2、編輯項目文件(NetCoreTemplate.Web.c ...
  • 2020 年 7 月 30 日, 由.NET基金會和微軟 將舉辦一個線上和為期一天的活動,包括 微軟 .NET 團隊的演講者以及社區的演講者。本次線上大會 專註.NET框架構建微服務,演講者分享構建和部署雲原生應用程式的最佳實踐、模式、提示和技巧。有關更多信息和隨時瞭解情況:https://focu... ...
  • #abp框架Excel導出——基於vue #1.技術棧 ##1.1 前端採用vue,官方提供 UI套件用的是iview ##1.2 後臺是abp——aspnetboilerplate 即abp v1,https://github.com/aspnetboilerplate/aspnetboilerp ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:碧茂大數據 PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取 input()輸入 Python提供了 input() 內置函數從標準輸入讀入一 ...
  • 從12年到20年,python以肉眼可見的趨勢超過了java,成為了當今It界人人皆知的編程語言。 python為什麼這麼火? 網路編程語言搜索指數 適合初學者 Python具有語法簡單、語句清晰的特點,這就讓初學者在學習階段可以把精力集中在編程對象和思維方法上。 大佬都在用 Google,YouT ...
  • 在社會上存在一種普遍的對培訓機構的學生一種歧視的現象,具體表現在,比如:當你去公司面試的時候,一旦你說了你是培訓機構出來的,那麼基本上你就涼了,那麼你瞞著不說,然後又通過了面試成功入職,但是以後一旦在公司被髮現有培訓經歷,可能會面臨被降薪,甚至被辭退,培訓機構出來的學生,在用人單位眼裡就是能力低下的 ...
  • from typing import List# 這道題看了大佬寫的代碼,經過自己的理解寫出來了。# 從最外圍的四周找有沒有為O的,如果有的話就進入深搜函數,然後深搜遍歷# 判斷上下左右的位置是否為Oclass Solution: def solve(self, board: List[List[s ...
  • import requests; import re; import os; # 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, li ...
  • import requests; import re; import os; import parsel; 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537. ...