Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Существует множество поставщиков конфигурации , доступных для распространенных источников конфигурации, таких как ФАЙЛЫ JSON, XML и INI. Возможно, потребуется реализовать настраиваемый поставщик конфигурации, если один из доступных поставщиков не соответствует потребностям приложения. В этой статье вы узнаете, как реализовать настраиваемый поставщик конфигурации, который использует базу данных в качестве источника конфигурации.
Поставщик пользовательской конфигурации
В примере приложения показано, как создать базовый поставщик конфигурации, который считывает пары "ключ-значение конфигурации" из базы данных с помощью Entity Framework (EF) Core.
Поставщик имеет следующие характеристики.
- База данных в памяти EF используется для демонстрационных целей.
- Чтобы использовать базу данных, требующую строки подключения, получите строку подключения из промежуточной конфигурации.
- Поставщик считывает таблицу базы данных в конфигурации при запуске. Поставщик не запрашивает базу данных для каждого ключа.
- Перезагрузка при изменении конфигурации не реализована, поэтому обновление базы данных уже после запуска приложения не изменяет его настройки.
Определите Settings сущность типа записи для хранения значений конфигурации в базе данных. Например, можно добавить файл Settings.cs в папку Models :
namespace CustomProvider.Example.Models;
public record Settings(string Id, string? Value);
Сведения о типах записей см. в разделе "Типы записей" в C#.
Добавьте EntityConfigurationContext в хранилище и обратитесь к настроенным значениям.
Providers/EntityConfigurationContext.cs:
using CustomProvider.Example.Models;
using Microsoft.EntityFrameworkCore;
namespace CustomProvider.Example.Providers;
public sealed class EntityConfigurationContext(string? connectionString) : DbContext
{
public DbSet<Settings> Settings => Set<Settings>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
_ = connectionString switch
{
{ Length: > 0 } => optionsBuilder.UseSqlServer(connectionString),
_ => optionsBuilder.UseInMemoryDatabase("InMemoryDatabase")
};
}
}
Переопределив OnConfiguring(DbContextOptionsBuilder), можно использовать соответствующее подключение к базе данных. Например, если строка подключения была предоставлена, можно подключиться к SQL Server, в противном случае можно использовать базу данных в памяти.
Создайте класс, который реализует интерфейс IConfigurationSource.
Providers/EntityConfigurationSource.cs:
using Microsoft.Extensions.Configuration;
namespace CustomProvider.Example.Providers;
public sealed class EntityConfigurationSource(
string? connectionString) : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder) =>
new EntityConfigurationProvider(connectionString);
}
Создайте пользовательский поставщик конфигурации путем наследования от ConfigurationProvider. Поставщик конфигурации инициализирует пустую базу данных. Так как конфигурационные ключи не учитывают регистр, словарь, используемый для инициализации базы данных, создается с помощью функции сравнения без учета регистра (StringComparer.OrdinalIgnoreCase).
Providers/EntityConfigurationProvider.cs:
using CustomProvider.Example.Models;
using Microsoft.Extensions.Configuration;
namespace CustomProvider.Example.Providers;
public sealed class EntityConfigurationProvider(
string? connectionString)
: ConfigurationProvider
{
public override void Load()
{
using var dbContext = new EntityConfigurationContext(connectionString);
dbContext.Database.EnsureCreated();
Data = dbContext.Settings.Any()
? dbContext.Settings.ToDictionary(
static c => c.Id,
static c => c.Value, StringComparer.OrdinalIgnoreCase)
: CreateAndSaveDefaultValues(dbContext);
}
static Dictionary<string, string?> CreateAndSaveDefaultValues(
EntityConfigurationContext context)
{
var settings = new Dictionary<string, string?>(
StringComparer.OrdinalIgnoreCase)
{
["WidgetOptions:EndpointId"] = "b3da3c4c-9c4e-4411-bc4d-609e2dcc5c67",
["WidgetOptions:DisplayLabel"] = "Widgets Incorporated, LLC.",
["WidgetOptions:WidgetRoute"] = "api/widgets"
};
context.Settings.AddRange(
[.. settings.Select(static kvp => new Settings(kvp.Key, kvp.Value))]);
context.SaveChanges();
return settings;
}
}
Метод AddEntityConfiguration расширения позволяет добавить источник конфигурации в базовый ConfigurationManager экземпляр.
Extensions/ConfigurationManagerExtensions.cs
using CustomProvider.Example.Providers;
namespace Microsoft.Extensions.Configuration;
public static class ConfigurationManagerExtensions
{
public static ConfigurationManager AddEntityConfiguration(
this ConfigurationManager manager)
{
var connectionString = manager.GetConnectionString("WidgetConnectionString");
IConfigurationBuilder configBuilder = manager;
configBuilder.Add(new EntityConfigurationSource(connectionString));
return manager;
}
}
ConfigurationManager Так как это реализация IConfigurationBuilder и IConfigurationRoot, метод расширения может получить доступ к конфигурации строк подключения и добавить EntityConfigurationSource.
В следующем коде показано, как использовать настраиваемый EntityConfigurationProvider в Program.cs:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using CustomProvider.Example;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddEntityConfiguration();
builder.Services.Configure<WidgetOptions>(
builder.Configuration.GetSection("WidgetOptions"));
using IHost host = builder.Build();
WidgetOptions options = host.Services.GetRequiredService<IOptions<WidgetOptions>>().Value;
Console.WriteLine($"DisplayLabel={options.DisplayLabel}");
Console.WriteLine($"EndpointId={options.EndpointId}");
Console.WriteLine($"WidgetRoute={options.WidgetRoute}");
await host.RunAsync();
// Sample output:
// WidgetRoute=api/widgets
// EndpointId=b3da3c4c-9c4e-4411-bc4d-609e2dcc5c67
// DisplayLabel=Widgets Incorporated, LLC.
Использование поставщика
Чтобы использовать настраиваемый поставщик конфигурации, можно использовать шаблон параметров. Используя пример приложения, определите объект параметров для представления параметров мини-приложения.
namespace CustomProvider.Example;
public class WidgetOptions
{
public required Guid EndpointId { get; set; }
public required string DisplayLabel { get; set; } = null!;
public required string WidgetRoute { get; set; } = null!;
}
Вызов Configure регистрирует экземпляр конфигурации, к которому TOptions привязывается.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using CustomProvider.Example;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddEntityConfiguration();
builder.Services.Configure<WidgetOptions>(
builder.Configuration.GetSection("WidgetOptions"));
using IHost host = builder.Build();
WidgetOptions options = host.Services.GetRequiredService<IOptions<WidgetOptions>>().Value;
Console.WriteLine($"DisplayLabel={options.DisplayLabel}");
Console.WriteLine($"EndpointId={options.EndpointId}");
Console.WriteLine($"WidgetRoute={options.WidgetRoute}");
await host.RunAsync();
// Sample output:
// WidgetRoute=api/widgets
// EndpointId=b3da3c4c-9c4e-4411-bc4d-609e2dcc5c67
// DisplayLabel=Widgets Incorporated, LLC.
Приведенный выше код настраивает WidgetOptions объект из "WidgetOptions" раздела конфигурации. Это активирует шаблон параметров, предоставляя представление настроек EF, готовое к внедрению зависимостей. Параметры в конечном счете предоставляются от пользовательского поставщика конфигурации.
См. также
- Конфигурация в .NET
- поставщики конфигурации в .NET
- Шаблон параметров в .NET
- Внедрение зависимостей в .NET