在 AppConfig.json 中存储对象的最佳方式

Optimal way to store objects in AppConfig.json

我的AppConfig.json:

{
     "MyTimeZone: "CET",
     "RegularString" : "SomeValue",
     "AnArray" : ["1","2"]
}

我的 POCO class:

public class Settings
{
     public TimeZoneInfo MyTimeZone { get; set; }
     public string RegularString { get; set; }
     public IList<string> AnArray { get; set; }
}

Registry.cs:

var configuration = GetConfiguration("AppSettings.json");
services.Configure<Settings>(configuration.GetSection("Settings"));

这当然不会将“CET”绑定到有效的 TimeZoneInfo 对象中。现在的问题是我的应用程序(一个网络应用程序)中从字符串转换为 TimeZoneInfo 的最佳位置是什么?有没有一种方法可以根据特定规则自动将字符串配置值转换为对象,而无需创建自定义转换器?

引用Use DI services to configure options

services.AddOptions<Settings>()
    .Configure<IConfiguration>((setting, configuration) => {
        var section = config.GetSection("Settings");
        //This will populate the other properties that can bind by default
        section.Bind(setting);

        //this will extract the remaining value and set it mnually
        string value = section.GetValue<string>("MyTimeZone");
        TimeZoneInfo info = TimeZoneInfo.FindSystemTimeZoneById(value);
        setting.MyTimeZone = info;
    });

复杂的设置值可以通过 DI 直接从配置中提取,用于创建时区并将其应用于设置。

这只是我个人的意见,但我更喜欢 MyTimeZone 是一个 json 对象而不是一个字符串。考虑以下因素:

"Settings": {
    "MyTimeZone": {
      "ConfigureTimeZoneById":  "CET"
    },
    "RegularString": "SomeValue",
    "AnArray": [ "1", "2" ]
  }

MyTimeZone.ConfigureTimeZoneById 不是实际数据对象的一部分。它只是将对象绑定到配置的代理。这就是 TimeZone class 的样子:

public class TimeZone
    {
        private string configureTimeZoneById { get; set; }
        public string ConfigureTimeZoneById
        {
            get { return configureTimeZoneById; }
            set
            {
                configureTimeZoneById = value;
                InitializeTimeZone(value);
            }
        }
        public string TimeZoneId { get; set; }
        public string OtherProperties { get; set; }

        private void InitializeTimeZone(string id)
        {
            var getTimeZone = TimeZonesDataset().FirstOrDefault(tzon => tzon.TimeZoneId.Equals(id));
            if (getTimeZone != null)
            {
                this.TimeZoneId = getTimeZone.TimeZoneId;
                this.OtherProperties = getTimeZone.OtherProperties;
            }
        }







        //dummy dataset
        private List<TimeZone> TimeZonesDataset() => new List<TimeZone> {
            new TimeZone{TimeZoneId = "CET", OtherProperties = "Dummy properties to prove point"},
            new TimeZone{TimeZoneId = "GMT", OtherProperties = default},
        };