我应该使用泛型来简化我的配置提供程序类
本文关键字:配置 程序 我的 泛型 我应该 | 更新日期: 2023-09-27 18:10:24
我正在尝试编写一个配置管理器,可以从不同的提供者(例如设置文件,环境变量,数据库等)提供配置设置。
我设想的设置将是字符串、整型或双精度,并将由名称
标识。设置是通过类实现的:
public interface IConfigurationManagerProvider
{
T GetSetting<T>(string name);
IEnumerable<ConfigurationSetting> GetKnownSettings();
}
作为一个开始,我试图写一个提供者返回环境变量
public class EnvironmentVariableProvider : IConfigurationManagerProvider
{
public T GetSetting<T>(string name)
{
string value = Environment.GetEnvironmentVariable(name);
return value as T;
}
public IEnumerable<ConfigurationSetting> GetKnownSettings()
{
return new List<ConfigurationSetting>
{
new ConfigurationSetting("MY_TRACING", typeof (String)),
};
}
}
但是这不会编译,因为它不能强制转换为T。如果我加入一个类约束这就限制了我使用字符串
public T GetSetting<T>(string name) where T : class
{
string value = Environment.GetEnvironmentVariable(name);
return value as T;
}
实际上这个提供程序只能提供字符串(其他提供程序会有所不同),但是我希望代码访问配置设置尽可能干净,使用类似的东西:
public interface IConfigurationManagerConsumer
{
T GetConfiguration<T>(string name, T systemDefault);
}
并像这样使用:
string tracing = ConfigurationManager.GetConfiguration("MY_TRACING", "Unknown");
或:
int maxUserCount = = ConfigurationManager.GetConfiguration("Max User Count", 10);
或:
double pi = ConfigurationManager.GetConfiguration("PI", 3.14159);
我走的方向对吗?
使用转换。ChangeType
return (T)Convert.ChangeType(value, typeof(T));
我有一个模糊类似的变量提供程序接口,其中我没有使用泛型。我从泛型开始,发现它并没有提高代码的可读性或性能,特别是因为类型很少,而且从一开始就知道。毕竟,您没有得到任何动态的东西,它是从您给出的默认值推断类型的。我还希望我的变量提供程序可以在不提供默认值的情况下使用,并且不想为此使用不同的语法。
所以我的包含两个层次。一个是我在代码中使用的公共接口提供程序,它可以在以下示例中使用:
IVariableProvider var;
// providing default value
double pi = var.Double["pi", 3.14159];
// no default value, also bool is just an int, converted by the IVariableProvider.
bool answer = var.Bool["answerswer"];
int number = var.Int["number"];
if(var.Str.ContainsKey("text"))
{
string text = var.Str["text"];
...
}
如果需要,我可以为var.Float, var.Long等添加公共接口。
下面,IVariableProvider
可以被赋予不同的"源"来获取变量。源只公开字符串和整数。它也可以使用其他的IVariableProvider
作为源。当我调用var.Double["pi"]
时,它检查是否有任何源可以为键"pi"提供字符串变量,然后检查double.Parse()
并返回它。
最终,你可以这样做。如果您使用这样的泛型,然后希望使用它而不使用默认值,则必须使用不同的语法来指定类型。