国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[Asp.net 5] Options-配置文件之后的配置

2019-11-17 02:09:17
字體:
來源:轉載
供稿:網友

[asp.net 5] Options-配置文件之后的配置

今天要講的是OptionsModel解決方案,整個解決方案中也只有Microsoft.Framework.OptionsModel一個工程。按照表面文字OptionsModel應該翻譯成選項模型,但是這個詞沒表現它實際的含義,我覺得稱呼它為配置選項好些,不過為了原滋原味,我們還是用英文的:Configuration和OptionsModel表示它們。

什么是OptionsModel

在之前的配置文件一節([Asp.net 5] Configuration-新一代的配置文件)我們介紹過配置文件最后生成的是IConfiguration對象,但是IConfiguration可能包含很多信息混雜在一起。比如設置日志的等級Level、連接數據庫的字符串connectionstring等。我們有時候不希望直接使用IConfiguration對象(比如對象中的配置項會變動),而是抽取一部分有用的信息以及一些其他值構成的具體的實體對象,那么這個從配置文件之后抽取的配置,就可以叫做OptionsModel。

簡而言之:IConfiguration是配置文件的抽象;OptionsModel配置文件之后的配置,是直接對于系統的配置項。

OptionsModel的特點與實現

這類對象的特點很明顯一般都是只包含一些屬性,并無具體的內部邏輯;但是這種配置可能不是僅有一個:比如有數據庫的connectionModel,而日志可能有LogOption。而且讓這些OptionsModel實現統一的接口也不是現實的,也沒有實際意義。那么如何實現Configuration到OptionsModel的轉換呢?

答案很簡單:Binder(神奇的Binder)。

        [Fact]        public void CanReadComplexPRoperties()        {            var dic = new Dictionary<string, string>            {                {"Integer", "-2"},                {"Boolean", "TRUe"},                {"Nested:Integer", "11"}            };            var builder = new ConfigurationBuilder(new MemoryConfigurationSource(dic));            var config = builder.Build();            var options = ConfigurationBinder.Bind<ComplexOptions>(config);            Assert.True(options.Boolean);            Assert.Equal(-2, options.Integer);            Assert.Equal(11, options.Nested.Integer);        }

如何DI?

很多工程使用了DependencyInjection(依賴注入),而OptionsModel是比較基礎的配置,幾乎可以肯定內部用到OptionsModel的類會被注入,并且使用類型注冊的方式注入。那么DependencyInjection內部肯定會遞歸到OptionsModel類,所以OptionsModel類也必須要進行注入,那么如何實現?

答曰:使用實例(Instance)直接注入到該類類型。[services.AddInstance(serviceType, type.Assembly.CreateInstance(type));]

如果我對于多個OptionsModel注冊,但是我可以通過命名方式注入,還可以進行排序,那又該如何實現?

答曰:Microsoft.Framework.OptionsModel。

Microsoft.Framework.OptionsModel

類文件分類

在Microsoft.Framework.OptionsModel中,使用泛型的方式進行注入,之后以泛型的方式獲取注入;但是注入的類和獲取的泛型類確是不完全一致的。

  • 注入的類和接口:IConfigureOptions<in TOptions>、ConfigureOptions<TOptions>、ConfigureFromConfigurationOptions<TOptions>
  • 獲取注入的類和接口:IOptions<out TOptions>、OptionsManager<TOptions>
  • 注冊的擴展類:OptionsServiceCollectionExtensions
  • 其他:OptionsConstants

注入類和接口

IConfigureOptions<in TOptions>、ConfigureOptions<TOptions>、ConfigureFromConfigurationOptions<TOptions>這幾個類和接口的關系為:

    public interface IConfigureOptions<in TOptions>    {        int Order { get; }        void Configure(TOptions options, string name = "");    }
IConfigureOptions
    public class ConfigureOptions<TOptions> : IConfigureOptions<TOptions>    {        public ConfigureOptions([NotNull]Action<TOptions> action)        {            Action = action;        }        public Action<TOptions> Action { get; private set; }        public string Name { get; set; } = "";        public virtual int Order { get; set; } = OptionsConstants.DefaultOrder;        public virtual void Configure([NotNull]TOptions options, string name = "")        {            // Always invoke the action if no Name was specified, otherwise only if it was the requested name            if (string.IsNullOrEmpty(Name) || string.Equals(name, Name, StringComparison.OrdinalIgnoreCase))            {                Action.Invoke(options);            }        }    }
ConfigureOptions
    public class ConfigureFromConfigurationOptions<TOptions> : ConfigureOptions<TOptions>    {        public ConfigureFromConfigurationOptions([NotNull] IConfiguration config)            : base(options => ConfigurationBinder.Bind(options, config))        {        }    }
ConfigureFromConfigurationOptions

注入類和接口的注入

在OptionsServiceCollectionExtensions中提供了三種注冊方式(實際是七個方法和重載):

  • 直接注冊實現IConfigureOptions<in TOptions>類型的數據。(假設實現類的類型為OptionsDev,則實際注冊[services.AddTransient(IConfigureOptions<T>,OptionsDev)])
  • 提供Action<TOptions>進行注冊。(創建實例instanceA=new ConfigureOptions<TOptions>(setupAction),之后注冊[services.AddInstance(IConfigureOptions<T>,configureInstance)])
  • 提供IConfiguration進行注冊。(創建實例instanceA=new ConfigureFromConfigurationOptions<TOptions>(setupAction),之后注冊[services.AddInstance(IConfigureOptions<T>, configureInstance)])
    public static class OptionsServiceCollectionExtensions    {        public static IServiceCollection AddOptions([NotNull]this IServiceCollection services)        {            services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));            return services;        }        private static bool IsAction(Type type)        {            return (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Action<>));        }        private static IEnumerable<Type> FindIConfigureOptions(Type type)        {            var serviceTypes = type.GetTypeInfo().ImplementedInterfaces                .Where(t => t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == typeof(IConfigureOptions<>));            if (!serviceTypes.Any())            {                string error = "TODO: No IConfigureOptions<> found.";                if (IsAction(type))                {                    error += " did you mean Configure(Action<T>)";                }                throw new InvalidOperationException(error);            }            return serviceTypes;        }        public static IServiceCollection ConfigureOptions([NotNull]this IServiceCollection services, Type configureType)        {            var serviceTypes = FindIConfigureOptions(configureType);            foreach (var serviceType in serviceTypes)            {                services.AddTransient(serviceType, configureType);            }            return services;        }        public static IServiceCollection ConfigureOptions<TSetup>([NotNull]this IServiceCollection services)        {            return services.ConfigureOptions(typeof(TSetup));        }        public static IServiceCollection ConfigureOptions([NotNull]this IServiceCollection services, [NotNull]object configureInstance)        {            var serviceTypes = FindIC
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鲁山县| 宽甸| 乐昌市| 嘉禾县| 和硕县| 邮箱| 巢湖市| 萍乡市| 裕民县| 四子王旗| 巴中市| 顺义区| 双江| 岗巴县| 黑水县| 东平县| 株洲县| 西华县| 濉溪县| 疏附县| 江川县| 沅陵县| 喀喇沁旗| 大姚县| 南京市| 股票| 沈丘县| 武鸣县| 温泉县| 临湘市| 咸阳市| 彰化市| 新绛县| 明星| 凌云县| 上蔡县| 西畴县| 建湖县| 曲松县| 尚义县| 淮南市|