我正在创建一个可以处理设置和加载/保存设置的dll。
我的设置类包含string Path
,DateTime LastOpened
等属性。
设置可以是任何设置,唯一的要求是它有一种默认值的方法。
有一个不同的类负责加载/保存设置。此类可以采用任何设置类和(反)序列化为任何文件格式。例如,它可以从XML文件加载类型的设置,或者从JSON文件加载相同类型的设置。
我的设计最终变得有些怪异。
我为所有设置类定义了一个接口,以便我知道DefaultSettings()
可用。
interface ISettings<T>
{
T DefaultSettings();
}
我的设置类可能如下所示:
public class MySettings : ISettings<MySettings>
{
public DateTime LastOpened;
public string Path;
public MySettings DefaultSettings()
{
LastOpened = DateTime.Now;
Path = @"c:\";
}
}
看起来非常奇怪,实现类我告诉它自己的接口。
加载/保存类实现了这个接口:
interface ISettingsFile<T>
{
T Load(string file);
void Save();
}
假设我想从MySettings
加载XmlSettingsFile<MySettings>
。
我必须写一些丑陋的东西,如
MySettings mySettings = new MySettings();
XmlSettingsFile<MySettings> file = new XmlSettingsFile<MySettings>();
try {
mySettings = file.Load();
} catch (FileNotFoundException)
{
mySettings = mySettings.DefaultSettings();
}
这太奇怪和丑陋了。必须有更好的方法来做到这一点。
你有什么好主意吗?
答案 0 :(得分:2)
我认为你的做法并不丑陋。使用中间字符串表示或类似的东西当然更好。
因此我会说你的方法很好,保持原样。
答案 1 :(得分:0)
这样的事情怎么样:
interface ISettings
{
public string GetSetting(string settingName, string defaultValue);
}
所以不要试图将设置表示为属性,而是使用命名值。这使得更容易考虑加载/保存设置,并且更容易使方法重载以将责任传递给不同的类。如果你愿意的话,你可以用动态完成这一切,但我个人喜欢这种模式,它让事情变得简单。
您也可以添加泛型,但通常我会发现这样的一些方法就足够了:
public bool GetSettingBool(string settingName, bool defaultValue);
答案 2 :(得分:0)
这会抽象出你的读者实现(xml,json,等等)......
public interface IConfigurationReader
{
T Read<T>(string configKey);
}
public class Configuration
{
private readonly IConfigurationReader _reader;
public Configuration(IConfigurationReader reader)
{
_reader = reader;
}
public string Path
{
get
{
var path = _reader.Read<string>("Path");
return path;
}
}
}
public class ApplicationConfigFileReader : IConfigurationReader
{
public T Read<T>(string configKey)
{
var settingValue = System.Configuration.ConfigurationManager.AppSettings[configKey];
return (T)Convert.ChangeType(settingValue, typeof(T));
}
}
//sample usage
class Program
{
static void Main(string[] args)
{
IConfigurationReader reader = new ApplicationConfigFileReader();
var config = new Configuration(reader);
Console.WriteLine(config.Path);
Console.ReadKey();
}
}
我的Reader实现只是作为读取应用程序配置文件的框架类型的适配器。
如果您有很多设置,按类别/区域将它们分组到不同的界面中会很有用。