自定义区域配置扩展 (中文 (Chinese Simplified))

自定义区域配置扩展

Comments

NOTE: Apart from English (and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.

Friday, 27 September 2024

//

Less than a minute

一. 导言 导言 导言 导言 导言 导言 一,导言 导言 导言 导言 导言 导言

似乎每个人都有这个代码的版本, 我第一次见到这个方法, 菲利普 W 最近我的老同事菲尔·哈克 其版本.

仅仅为了完成,这是我如何做到的。

为什么?

为何要让配置更容易操作? 此时此刻,第一 使用的方式正在使用 IOptions<T>IOptionsSnapshot<T> 但它是一个有点 痛苦的工作。 这种方法可以让您以更自然的方式与配置合作。 限制在于你不能使用 IOptions<T> 样式,所以您无法在不重新启动应用程序的情况下重新装入配置 。 但老实说,这几乎是我从未想做的事。

《刑法典》

在我的版本中,我使用最近的静态界面成员来具体说明,这一类的所有情况都必须宣布 Section 财产。 此选项用于从配置中获取区域 。

public interface IConfigSection {
    public static abstract string Section { get; }
}

因此,对于每一项执行,你然后具体说明本部分应受下列约束的哪一节:

public class NewsletterConfig : IConfigSection
{
    public static string Section => "Newsletter";
    
    public string SchedulerServiceUrl { get; set; } = string.Empty;
    public string AppHostUrl { get; set; } = string.Empty;
}

在此情况下,它正在寻找一个区域 在配置中被调用 Newsletter.

  "Newsletter": {
      "SchedulerServiceUrl" : "http://localhost:5000",
        "AppHostUrl" : "https://localhost:7240"
    
  }

然后,我们将能够将这一点约束在 Program.cs 像这样的文件 :


var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
services.ConfigurePOCO<NewsletterConfig>(config);

我们也可以从中获取配置值 Program.cs 像这样的文件 :

var newsletterConfig = services.ConfigurePOCO<NewsletterConfig>(config);

甚至为了 WebApplicationBuilder 类似 :

var newsletterConfig = builder.Configure<NewsletterConfig>();

注:由于建造者可以使用 ConfigurationManager 它不需要通过。

意思是您现在可以选择如何绑定配置 。

另一个好处是,如果你以后需要使用这些数值 Program.cs 然后,该对象可供您使用。

推广方法

为了让这一切成为可能,我们有一个相当简单的扩展方法, 将配置与等级绑在一起。

以下代码允许:

// These get the values and bind them to the class while adding these to Singleton Scope
var newsletterConfig = services.ConfigurePOCO<NewsletterConfig>(config);
var newsletterConfig = services.ConfigurePOCO<NewsletterConfig>(configuration.GetSection(NewsletterConfig.Section));
// Or for Builder...These obviously only work for ASP.NET Core applications, take them out if you are using this in a different context.
var newsletterConfig = builder.Configure<NewsletterConfig>();
var newsletterConfig = builder.Configure<NewsletterConfig>(NewsletterConfig.Section);
// These just return a dictionary, which can be useful to get all the values in a section
var newsletterConfig = builder.GetConfigSection<NewsletterConfig>();

所有这一切都由以下扩展类启用 。

您可以看到它的主要动力是使用静态界面成员指定区域名称。 然后用它从配置中获取区域 。

namespace Mostlylucid.Shared.Config;

public static class ConfigExtensions {
    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfigurationSection configuration)
        where TConfig : class, new() {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));
        
        var config = new TConfig();
        configuration.Bind(config);
        services.AddSingleton(config);
        return config;
    }

    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, ConfigurationManager configuration)
        where TConfig : class, IConfigSection, new()
    {
        var sectionName = TConfig.Section;
        var section = configuration.GetSection(sectionName);
        return services.ConfigurePOCO<TConfig>(section);
    }
    
    public static TConfig Configure<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var services = builder.Services;
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        return services.ConfigurePOCO<TConfig>(configuration.GetSection(sectionName));
    }
    

    public static TConfig GetConfig<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        var section = configuration.GetSection(sectionName).Get<TConfig>();
        return section;
        
    }
    
    public static Dictionary<string, object> GetConfigSection(this IConfiguration configuration, string sectionName) {
        var section = configuration.GetSection(sectionName);
        var result = new Dictionary<string, object>();
        foreach (var child in section.GetChildren()) {
            var key = child.Key;
            var value = child.Value;
            result.Add(key, value);
        }
        
        return result;
    }
    
    public static Dictionary<string, object> GetConfigSection<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        return configuration.GetConfigSection(sectionName);
    }
}

使用中

使用这些很简单。 在任何需要这种配置的班级中,您都可以这样直接注射:

public class NewsletterService(NewsletterConfig config {
 
}

在结论结论中

嗯,就是这样... 很简单... 但它是一个技术 我在所有项目中使用的技巧。 这是一个很好的方式 与配置工作 和我认为它 有点自然 比 IOptions<T> 模式。

logo

©2024 Scott Galloway