Как прочитать параметры конфигурации перед инициализацией хоста в ASP .NET Core? - PullRequest
3 голосов
/ 24 октября 2019

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

В ASP .NET Core 2.x для чтения настроек перед инициализацией хоста приложения, который я использовал для выполненияследующее:

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = WebHost.CreateDefaultBuilder()
        .UseStartup<Startup>()
        .UseConfiguration(configuration)
        .Build();

    //...
}

В ASP .NET Core 3.x WebHost устарело в пользу .NET Generic Host .
.NET Generic Host имеет только .ConfigureHostConfiguration() и .ConfigureAppConfiguration(), которые не принимают встроенную конфигурацию в качестве параметра, но вместо этого принимают только делегата, используемого для настройки конфигурации.

Для рабочих нагрузок HTTP вы все равно можете использовать метод .UseConfiguration(), если он выставленIWebHostBuilder и, по сути, аналогично предыдущему:

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>()
                .UseConfiguration(configuration);
        })
        .Build();

    //...
}

Но это работает только для рабочих нагрузок HTTP, а не для Worker Services.

Чтобы получить конфигурацию перед настройкой хоста, я предложил следующий подход:

public static void Main(string[] args)
{
    //...

    var configuration = ConfigureConfigurationBuilder(args)
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder => ConfigureConfigurationBuilder(args, builder))
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .Build();

    //...
}

public static IConfigurationBuilder ConfigureConfigurationBuilder(string[] args, IConfigurationBuilder configurationBuilder = null)
{
    configurationBuilder ??= new ConfigurationBuilder();

    configurationBuilder
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json");

    return configurationBuilder;
}

По сути, я написал метод, который устанавливает ConfigurationBuilder и возвращает его, так что яможет реуста же конфигурация. Это работает на практике, но я собираю одну и ту же конфигурацию дважды.

Существует ли более простой / более правильный способ (который работает для рабочих нагрузок HTTP и не-HTTP) для создания и повторного использованияконфигурация перед настройкой хоста?

Ответы [ 2 ]

5 голосов
/ 28 октября 2019

Вы можете очистить источники по умолчанию, добавленные CreateDefaultBuilder, а затем добавить предварительно построенный IConfiguration с помощью AddConfiguration метода расширения .

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder =>
        {
            builder.Sources.Clear();
            builder.AddConfiguration(configuration);
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .Build();

    //...
}
0 голосов
/ 28 октября 2019

Правильный вопрос, вам действительно нужна конфигурация для вашей конфигурации? Вы можете использовать другой файл и связать его напрямую с сущностью

configuration.GetSection("entity").Bind(entity);

Если я не понял, что вы имеете в виду, все, что я знаю, это то, что вам понадобится для установки зависимостей, или вы не можетеиспользуйте его, поэтому вместо этого вы можете использовать расширения для вашей коллекции сервисов, чтобы делать то, что вы хотите с вашей конфигурацией, и вы получите установку в своем контейнере

...