. NET Внедрение зависимостей в ядро ​​консольного приложения - как настроить использование Newtonsoft. Json для десериализации IOptions <> - PullRequest
0 голосов
/ 08 апреля 2020

Можно ли настроить консольное приложение. Net Core 3.1 для использования библиотеки Newtonsoft. Json для десериализации IOptions <> (из Microsoft.Extensions.Options) при чтении разделов json файл настроек?

 public MyService(IOptions<MyAppDataSettings> MyAppDataOptions)
 {
     var myAppDataOptions = MyAppDataOptions?.Value ?? throw new ArgumentNullException(nameof(MyAppDataSettings));
 }

Результат отличается от десериализации напрямую с System.Text. Json:

var appJsonData = System.Text.Json.JsonSerializer.Deserialize<MyAppDataSettings>(File.ReadAllText(appJsonPath));

Настройки содержат «упорядоченный» словарь. При непосредственном вызове десериализатора порядок ключей правильный, как в файле настроек json. Но значение, возвращаемое IOptions <>, содержит словарь с ключами, отсортированными по алфавиту. Затем я попытался принудительно использовать Newtonsoft Json:

private static void ConfigureServices(IConfiguration configuration, IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
        });

    services.Configure<MyAppDataSettings>(configuration.GetSection(nameof(MyAppDataSettings)));
    services.AddSingleton<IMyService, MyService>();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
         new HostBuilder()
             .ConfigureServices((context, services) =>
             {
                 ConfigureServices(context.Configuration, services);
             })
             .ConfigureAppConfiguration((context, configurationBuilder) =>
             {
                 var appExecPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
                 var appSettingsPath = Path.GetFullPath(Path.Combine(appExecPath, @"Settings"));

                 configurationBuilder
                     .SetBasePath(appSettingsPath)
                     .AddJsonFile("MySettings.json", false);
             });

Результат при использовании десериализатора Newtonsoft. Json такой же, как с System.Text. Json.

var appJsonData = JsonConvert.DeserializeObject<MyAppDataSettings>(File.ReadAllText(appJsonPath));

Таким образом, вопрос заключается в следующем: как десериализуются IOptions ? Я предполагаю, что "волхвы c" встречаются в библиотеке Microsoft.Extensions.Configuration. Json.

1 Ответ

0 голосов
/ 08 апреля 2020

Ни JSON, ни словарь не гарантируют порядок ключей. Согласно документации по словарю Словарь MSDN :

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

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

...