我正在创建一个平台/基础组件(一组.NET程序集),它将负责访问(读/写)配置值。该组件将由将在平台上创建的其他组件使用。
我希望这个组件易于为消费者使用,但也具有很高的可测试性和可维护性。在我目前的设计中,我有一个包含一些方法的静态类(ConfigurationManager)(例如GetKeyValueSetting)。此ConfigurationManager类的特殊之处在于,它既可以从本地.NET .config文件获取配置值,也可以从SharePoint列表(某些组件托管在共享SharePoint环境中)中获取配置值,甚至可以从另一个共享配置值存储中获取配置值。经理应该能够以优先的方式从多个地点阅读:
我知道静态类在可测试性,可扩展性等方面会产生很多问题,所以我不想使用它。我的下一个选择是Singleton,但就上述能力而言,这不是一个更好的解决方案。有什么想法可以提供更好的解决方案吗?
我目前的设计如下:
public static class ConfigurationManager
{
// internal for testability
internal IEnumerable<ISettingsProvider> SettingsProviders {get;set;}
// internal for testability
internal ISettingsProviderFactory ProvidersFactory {get;set;}
public static string GetKeyValueSetting(string key)
{
}
}
public interface ISettingsProvider
{
string GetKeyValueSetting(string key);
}
public class ConfigFileSettingsProvider : ISettingsProvider
{
}
public class SharePointSettingsProvider : ISettingsProvider
{
}
public class SharedStoreSettingsProvider : ISettingsProvider
{
}
public interface ISettingsProviderFactory
{
IEnumerable<ISettingsProvider> GetProviders();
}
答案 0 :(得分:1)
为什么不这样:
public abstract class ConfigurationManager
{
public abstract string GetKeyValueSetting(string key);
public static ConfigurationManager GetInstance()
{
return GetInstance(GetDefaultSettingProvider(), GetDefaultProviderFactory());
}
public static ConfigurationManager GetInstance(ISettingsProvider provider, IProviderFactory factory)
{
return new InternallyVisibleConfigurationManagerImplementation(provider, factory);
}
}
这有很多好处:
如果来电者真的讨厌这个,并且不介意他们的单位测试有时会调用sharepoint网站,你可以添加这样的便利方法:
public static string GetKeyValueSetting(string key)
{
return GetInstance().GetKeyValueSetting(key);
}
修改强>
要使用几个商店,请创建一个这样的类:
internal class OrderedCompositeSettingProvider : ISettingProvider
{
private readonly ISettingProvider[] _providers;
private OrderedCompositeSettingProvider(ISettingProvider[] providers)
{
_providers = providers;
}
internal static ISettingProvider GetInstance(params ISettingProvider[] providers)
{
return new OrderedCompositeSettingProvider(providers)
}
public string GetKeyValueSetting(string key)
{
foreach(var provider in _providers)
{
var setting = provider.GetKeyValueSetting(key);
if(!string.IsNullOrEmpty(setting)) return setting;
}
return string.empty;
}
}
然后在ConfigurationManager工厂方法中:
public static ConfigurationManager GetInstance()
{
return GetInstance(GetAppropriateProvider(), GetDefaultProviderFactory());
}
private static ISettingsProvider GetAppropriateProvider()
{
if(ShouldUseSharepoint())
return OrderedCompositeSettingProvider.GetInstance(new SharepointProvider(), new StoredSettingsProvider());
return OrderedCompositeSettingProvider.GetInstance(new ConfigFileProvider(), new StoredSettingsProvider());
}