【问题标题】:.NET Core console app dependency injection - how to configure usage of Newtonsoft.Json for deserializing IOptions<>.NET Core 控制台应用程序依赖注入 - 如何配置 Newtonsoft.Json 的使用以反序列化 IOptions<>
【发布时间】:2020-07-20 06:33:50
【问题描述】:

在读取 json 设置文件的部分时,是否可以配置 .Net Core 3.1 控制台应用程序以使用 Newtonsoft.Json 库来反序列化 IOptions(来自 Microsoft.Extensions.Options)?

 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 返回的值包含一个字典,其中的键按字母顺序排序。 然后我尝试强制使用 NewtonsoftJson:

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 是如何反序列化的?我想“魔法”发生在 Microsoft.Extensions.Configuration.Json 库中。

【问题讨论】:

    标签: json .net-core dependency-injection console-application settings


    【解决方案1】:

    JSON 和 Dictionary 都不能保证键的顺序。根据字典文档 MSDN Dictionary:

    出于枚举的目的,字典中的每个项目都被视为表示值及其键的 KeyValuePair 结构。返回项目的顺序未定义。

    根据我的经验,我强烈建议重新考虑您用于配置的方法并摆脱订单依赖性。

    【讨论】:

    • 你是对的,但是有定制的 OrderedDictionary 实现可用,它保持添加键的顺序。正如我所说,当直接反序列化时,这与 System.Text.Json 和 Newtonsoft.Json 实现完美结合。看起来 Microsoft.Extensions.Configuration.Json 实现存在问题。但由于我想保留 IOptions 依赖注入,我必须定义一个类并将有序字典替换为类实例列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2021-08-22
    • 2014-11-15
    • 2018-06-30
    • 2016-11-02
    • 2016-12-07
    相关资源
    最近更新 更多