Как использовать несколько разделов в одном интерфейсе asp.net core 6?

У меня есть несколько разделов в моем файле appsettings.json, который находится в приложении ASP.NET Core 6.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "OracleSettings": {
    "Host": "host.com",
    "Port": "1521"
  },
  "ElasticSettings": {
    "Hosts": "elastic.com"
  },
  "RedisSettings": {
    "Ip": "redis.com",
    "Timeout": 1,
    "Duration": 50
  }  
}

И я создал классы для секций.

public class OracleSettings
{
    public string Host { get; set; }
    public string Port { get; set; }
}

public class ElasticSettings
{
    public string Hosts { get; set; }
}

public class RedisSettings
{
    public string Ip { get; set; }
    public int Timout { get; set; }
    public int Duration { get; set; }
}

Я хочу получить доступ ко всем настройкам, используя только один интерфейс с именем IApplciationSettings.

public interface IApplciationSettings
{
    OracleSettings OracleSettings { get; set; }
    ElasticSettings ElasticSettings { get; set; }
    RedisSettings RedisSettings { get; set; }
}

добавление сервисов строителя:

builder.Services.Configure<ElasticSettings>(builder.Configuration.GetSection(nameof(ElasticSettings)));
builder.Services.Configure<OracleSettings>(builder.Configuration.GetSection(nameof(OracleSettings)));
builder.Services.Configure<RedisSettings>(builder.Configuration.GetSection(nameof(RedisSettings)));

Итак, я хочу привязать к интерфейсу IApplciationSettings все конфигурации и использовать его в инъекциях зависимостей конструктора, например:

[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
    readonly IProductService productService;

    public PoructController(
        IApplciationSettings settings, IProductService productService)
    {
        this.productService = productService;
        
        var oraclesetting = settings.OracleSettings;
    }
}

Как я могу это сделать?

Зачем вам интерфейс IApplciationSettings? Может ли этот класс быть простым классом данных, как OracleSettings и ElasticSettings?

Steven 23.04.2022 12:24
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
1
92
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете создать свою базу классов в своих IApplicationSettings, а в программе вы пишете следующее:

builder.Services.Configure<ApplicationSettings>(builder.Configuration);

то в вашем конструкторе вы

[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
    readonly IProductService productService;

    public PoructController(IOptions<ApplicationSettings> settings, IProductService productService)
    {
        this.productService = productService;
        
        var oraclesetting = settings.Value.OracleSettings;
    }
}

Я не хочу использовать IOptions в своих классах.

barteloma 23.04.2022 10:12

settings.Value возвращает весь объект applicationSettings.... если вы этого не хотите... в programa.cs вы можете извлечь IOptions<ApplicationSettings>, а затем зарегистрировать, как с областью видимости... но это не так элегантно var appSettings = Builder.Services.BuildServiceProvider().GetRequiredService<I‌​Options<ApplicationS‌​ettings>>().Value; builder.Services.AddScoped<IApplicationSettings, ApplicationSettings>();

Den 23.04.2022 10:38
Ответ принят как подходящий

Предполагая, что существует конкретная реализация IApplciationSettings

public class ApplciationSettings : IApplciationSettings {
    public OracleSettings OracleSettings { get; set; }
    public ElasticSettings ElasticSettings { get; set; }
    public RedisSettings RedisSettings { get; set; }
}

Извлеките параметры непосредственно из конфигурации и добавьте их в контейнер службы внедрения зависимостей.

//...

ApplciationSettings settings = builder.Configuration.Get<ApplciationSettings>();

if(settings == null) throw new Exception("message here"); //fail early

builder.Services.AddSingleton<IApplciationSettings>(settings);

//...

Метод расширения ConfigurationBinder.Get<T> связывает и возвращает указанный тип.

Attempts to bind the configuration instance to a new instance of type T. If this configuration section has a value, that will be used. Otherwise binding by matching property names against configuration keys recursively.

Это позволит вводить IApplciationSettings по желанию без необходимости тесной связи с IOptions.

Ссылка Привязать иерархическую конфигурацию

Другие вопросы по теме