.NET Core console应用程序依赖项注入-如何配置Newtonsoft.Json用于反序列化IOptions<&燃气轮机;

.NET Core console应用程序依赖项注入-如何配置Newtonsoft.Json用于反序列化IOptions<&燃气轮机;,json,.net-core,dependency-injection,console-application,settings,Json,.net Core,Dependency Injection,Console Application,Settings,在读取Json设置文件的部分时,是否可以将.Net Core 3.1控制台应用程序配置为使用Newtonsoft.Json库(从Microsoft.Extensions.Options)反序列化IOption public MyService(IOptions<MyAppDataSettings> MyAppDataOptions) { var myAppDataOptions = MyAppDataOptions?.Value ?? throw new Argumen

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

 public MyService(IOptions<MyAppDataSettings> MyAppDataOptions)
 {
     var myAppDataOptions = MyAppDataOptions?.Value ?? throw new ArgumentNullException(nameof(MyAppDataSettings));
 }
public MyService(IOptions MyAppDataOptions)
{
var myAppDataOptions=myAppDataOptions?.Value??抛出新的ArgumentNullException(nameof(MyAppDataSettings));
}
结果与直接使用System.Text.Json反序列化时不同:

var appJsonData = System.Text.Json.JsonSerializer.Deserialize<MyAppDataSettings>(File.ReadAllText(appJsonPath));
var-appJsonData=System.Text.Json.JsonSerializer.Deserialize(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);
             });

私有静态void配置服务(IConfiguration配置、iSeries收集服务)
{
services.AddControllers().AddNewtonsoftJson(选项=>
{
options.SerializerSettings.ContractResolver=新的DefaultContractResolver();
});
Configure(configuration.GetSection(nameof(MyAppDataSettings));
services.AddSingleton();
}
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
新主机生成器()
.ConfigureServices((上下文、服务)=>
{
配置服务(context.Configuration,services);
})
.ConfigureAppConfiguration((上下文,configurationBuilder)=>
{
var appExecPath=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
var appSettingsPath=Path.GetFullPath(Path.Combine(appExecPath,@“设置”);
配置生成器
.SetBasePath(应用设置路径)
.AddJsonFile(“MySettings.json”,false);
});
使用Newtonsoft.Json反序列化程序时的结果与使用System.Text.Json时的结果相同

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

所以问题是:IOptions实际上是如何反序列化的?我假设“魔力”出现在Microsoft.Extensions.Configuration.Json库中。

Json和Dictionary都不能保证密钥顺序。根据字典文档 :

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


根据我的经验,我强烈建议您重新考虑用于配置的方法,并消除顺序依赖性

JSON和字典都不能保证密钥顺序。根据字典文档 :

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


根据我的经验,我强烈建议您重新考虑用于配置的方法,并消除顺序依赖性

您是对的,但是有定制的OrderedDictionary实现可用,它们保持添加键的顺序。正如我所说的,当直接反序列化时,这对System.Text.Json和Newtonsoft.Json实现都非常有效。看起来Microsoft.Extensions.Configuration.Json实现存在问题。但是,由于我想保留IOptions依赖项注入,我必须定义一个类并用类实例列表替换有序字典。你是对的,但是有定制的OrderedDictionary实现可用,它们保持了添加键的顺序。正如我所说的,当直接反序列化时,这对System.Text.Json和Newtonsoft.Json实现都非常有效。看起来Microsoft.Extensions.Configuration.Json实现存在问题。但是,由于我想保留IOptions依赖项注入,我必须定义一个类,并用一个类实例列表替换有序字典。