NOTE: Apart from
(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>
Взірець.