2011-10-05 63 views
1

我正在尝试编写一个可以提供来自不同提供程序(例如设置文件,环境变量,数据库等)的配置设置的配置管理器。我是否应该使用泛型来简化我的配置提供者类?

我已经预想到的设置将是要么字符串,整数或双打,并通过经班提供

设置的名称,实施这个标识:

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. 我F I把一个类约束在那么这限制了我为字符串

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); 

上午我在正确的方向前进?

回答

3

使用Convert.ChangeType

return (T)Convert.ChangeType(value, typeof(T)); 
+0

干杯。我会认为这是一个暗示“是的,这是正确的方法”:) –

1

我有一个大体相似变量提供商的接口,这是我没有使用泛型。我从泛型开始,发现它并没有使代码更具可读性或表现性,特别是因为类型很少,并且从一开始就知道。毕竟,你没有获得任何动态的东西,它是从你给出的默认值推断出的类型。我还希望我的变量提供程序在没有提供默认值的情况下可用,并且不希望为此使用不同的语法。

所以我的矿井由两个层次组成。一个是公共接口提供者,我在代码中使用,它可以在这些例子中使用,如:

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["answer"]; 
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”提供一个字符串变量,然后返回它。

最终,你可以这样做。如果你使用那样的泛型,然后想使用它没有默认值,你将不得不使用不同的语法来指定类型。

+0

非常好,谢谢你给我一些想法。 –

相关问题