代码之家  ›  专栏  ›  技术社区  ›  Jonathan Allen

我可以在ASP中进行必要的配置吗。净核心?

  •  0
  • Jonathan Allen  · 技术社区  · 4 年前

    以下是我的启动代码:

    services.Configure<FooBarOptions>(Configuration.GetSection("FooBarOptions"));
    

    正如我所想,这是一个错误

    services.Configure<FooBarOptions>(Configuration.GetSection("FooBar"));
    

    很明显,输入错误导致配置无法加载。当所需的配置部分不存在时,是否有方法在启动过程中触发错误?

    1 回复  |  直到 4 年前
        1
  •  4
  •   abdusco    4 年前

    使用 PostConfigure<T> 带有一个回调,它将在每个 Configure<T> 被处决了。这将允许用户以任何顺序以任何方式配置选项,并允许您查看(未配置的)选项,并在需要时引发异常。

    class FooBarOptions
    {
        public string AString { get; set; }
    }
    
    services.PostConfigure<FooBarOptions>(options => {
        // ... validate configuration
        if (options.AString == null)
        {
            throw new InvalidProgramException($"{nameof(FooBarOptions)} is not configured properly");
        }
    });
    
    services.Configure<FooBarOptions>(Configuration.GetSection("FooBarOptions"));
    

    工具书类

        2
  •  1
  •   Tieson T.    4 年前

    如果您想让启动文件的“绑定”部分保持简洁,可以在 IConfiguration IServiceCollection 会有用的。下面是一个基本的实现。

    static class ConfigurationBindingExtensions
    {
        public static void BindSection<T>(this IConfiguration configuration, IServiceCollection services, string sectionName) where T : class
        {
            var config = configuration.GetSection(sectionName);
            if (config.Exists())
            {
                services.Configure<T>(config);
            }
            else
            {
                throw new ConfigurationSectionNotFoundException(sectionName);
            }
        }
    }
    
    
    [Serializable]
    class ConfigurationSectionNotFoundException : Exception, System.Runtime.Serialization.ISerializable
    {
        public string SectionName { get; set; }
    
        public ConfigurationSectionNotFoundException(string sectionName)
            : this(sectionName, string.Format("Section {0} was not found in the configuration file", sectionName))
        {
            this.SectionName = sectionName;
        }
    
        public ConfigurationSectionNotFoundException(string sectionName, string message)
            : base(message)
        {
            this.SectionName = sectionName;
        }
    
        protected ConfigurationSectionNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {
            if (info == null)
                throw new ArgumentNullException(nameof(info));
    
            SectionName = info.GetString("SectionName");
        }
    
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter = true)]
        public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException(nameof(info));
    
            info.AddValue("SectionName", SectionName);
    
            base.GetObjectData(info, context);
        }
    
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
        void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException(nameof(info));
    
            GetObjectData(info, context);
        }
    }
    
    

    你会这样称呼它:

    Configuration.BindSection<FooBarOptions>(services, "FooBar");
    

    如果未定义节,这将引发自定义异常——如果对您更有意义,您可以用其他内容替换它。可能是杀伤力太大了,但它能保持启动。漂亮整洁。

        3
  •  1
  •   Serge    4 年前

    试试这个

    var exist = Configuration.GetSection("FooBar").Exist();
    if (exist) services.Configure<FooBarOptions>(Configuration.GetSection("FooBar"));
    else ....throw exception
    
    推荐文章