我正在构建一个Azure Function应用程序,它需要一些初始配置才能工作。local.settings.json的values部分包含如下属性的键值对:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"MyConfiguration:AllowedEmailDomains": "gmail.com,hotmail.com"
}
}
我的配置类如下所示:
public class MyConfiguration
{
public List<string> AllowedEmailDomains { get; set; } = null;
}
我将其绑定如下:
builder.Services.AddOptions<MyConfiguration>().Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyConfiguration").Bind(settings);
});
显然,当前,该值绑定为具有单个字符串元素的列表。
这意味着我可以做这样的事情:
builder.Services.AddOptions<MyConfiguration>().Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyConfiguration").Bind(settings);
if (settings.AllowedEmailDomains != null) {
// split the string and update the property.
}
});
我知道我可以在应用程序配置中提供列表的值。然而,我更喜欢有一个单独的长字符串,我自己拆分,这样用户就不需要提供这些设置的负载,并且可以在应用程序配置中坚持一个字段。
有没有更好的方法可以做到这一点,这样我就可以阅读设置并直接进入列表?
您可以使用Singleton进行配置。
public static class GenericSingleton<T> where T : class
{
static volatile T _instance;
static object _lock = new object();
static GenericSingleton()
{
}
public static T Instance
{
get
{
if (_instance == null)
lock (_lock)
{
if (_instance == null)
{
ConstructorInfo constructor = null;
try
{
// Binding flags exclude generic constructors.
constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null);
}
catch (Exception exception)
{
throw new SingletonException(exception.Message);
}
if (constructor == null || constructor.IsAssembly)
// Also exclude internal renderers.
throw new SingletonException(string.Format("A private or protected constructor is missing for '{0}'.", typeof(T).Name));
_instance = (T)constructor.Invoke(null);
}
}
return _instance;
}
}
}
创建基本配置:
public class BaseAppConfiguration
{
internal static BaseAppConfiguration BaseConfig => GenericSingleton<BaseAppConfiguration>.Instance;
private readonly IConfigurationRoot ConfigurationRoot = null;
public BaseAppConfiguration()
{
var builder = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
ConfigurationRoot = builder.Build();
}
public RedisConfigurationSection RedisTokenConfig()
{
return
new RedisConfigurationSection()
{
Host = ConfigurationRoot["RedisTokenConfiguration:host"],
Port = int.Parse(ConfigurationRoot["RedisTokenConfiguration:port"]),
Password = ConfigurationRoot["RedisTokenConfiguration:password"],
DatabaseID = int.Parse(ConfigurationRoot["RedisTokenConfiguration:databaseID"])
};
}
public string GetConnectionString()
{
return ConfigurationRoot.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;
}
public string GetDatabaseProvider()
{
return ConfigurationRoot.GetSection("ConnectionStrings").GetSection("Provider").Value;
}
public string GetAppVersion()
{
return ConfigurationRoot.GetSection("Version").Value;
}
public EMailConfigurationSection GetEmailConfig()
{
return
new EMailConfigurationSection()
{
SmtpServer = ConfigurationRoot["EmailConfiguration:smtpServer"],
SmtpPort = int.Parse(ConfigurationRoot["EmailConfiguration:smtpPort"]),
Username = ConfigurationRoot["EmailConfiguration:username"],
Password = ConfigurationRoot["EmailConfiguration:password"]
};
}
}
并为每个应用程序创建附加配置:
public class ExampleAppConfiguration : BaseAppConfiguration
{
public ExampleAppConfiguration()
{
}
public static ExampleAppConfiguration Config => GenericSingleton<ExampleAppConfiguration>.Instance;
}