在 Windows Mobile 6.x 中添加配置文件支持






4.75/5 (5投票s)
学习如何在 .NET CF 中添加对 .config 文件的支持。
引言
Compact Framework 本身不包含对 .config 文件的原生支持。本文将解释如何将该支持重新构建到您的应用程序中,这非常简单。
创建 app.config
首先,您需要在您的项目中创建一个 app.config 文件。由于 .config 无法作为新项目项添加,因此您可以选择任何文件(.cs 即可),并将其命名为 app.config。您的新 app.config 文件将包含默认的命名空间/类垃圾信息。删除所有这些内容并创建您的 .config 文件。这个示例文件如下所示
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="Username" value="user"/>
<add key="Password" value="pass"/>
<add key="Port" value="1234"/>
</appSettings>
</configuration>
虽然 .NET CF 不包含任何读取 .config 的库,但当您编译应用程序时,app.config 文件会被正确重命名
在使用您的应用程序之前,您需要将此重命名的 .config 文件复制/粘贴到您的应用程序目录中,或者确保将其包含在您的 .CAB 设置项目中。
使用代码
CompactFrameworkSupplements.dll 中包含的 ConfigurationManager
类可以被引用并在任何 Windows Mobile 6 应用程序中使用,只需几行代码即可。
private void LoadAppSettings()
{
string error = string.Empty;
var cm = new ConfigurationManager();
if (cm.ValidateAppSettings(out error, new AppSettings()))
{
_appSettings = new AppSettings();
cm.LoadAppSettings(_appSettings);
textBox1.Text = "AppSettings loaded!";
}
else
textBox1.Text = error;
}
_appSettings 对象现在已加载了 .config 文件中的所有值。当您需要扩展您的应用程序并从 .config 文件中获取更多信息时,只需在 .config 文件中添加一个键/值对,并在您的 AppSettings 类中添加一个匹配的属性。就是这样!
让我们看看魔术是如何发生的
ValidateAppSettings
将任何错误传递出去,并接收您的类的一个实例,该实例将在您的应用程序中使用以保存 app.config 文件的内容。在这个例子中,我的类叫做 AppSettings
,如下所示
public class AppSettings
{
[Required(true)]
public string Username { get; set; }
[Required(true)]
public string Password { get; set; }
public int Port { get; set; }
}
ValidateAppSettings
有 3 个主要目的
- .config 文件是否包含
AppSettings
类中定义的每个属性的键? AppSettings
类中标记为Required
的所有属性是否在 .config 文件中具有值?- .config 文件中的值是否与
AppSettings
类中属性的预期数据类型匹配?
它看起来像这样
public bool ValidateAppSettings(out string error, object classInstanceToReadAppSettingNamesAndTypesFrom)
{
error = string.Empty;
var expectedSettings = new Dictionary<string, Type>();
var attrDictionary = new Dictionary<string, object[]>();
var pis = classInstanceToReadAppSettingNamesAndTypesFrom.GetType().GetProperties();
foreach (var pi in pis)
{
expectedSettings.Add(pi.Name, pi.PropertyType);
attrDictionary.Add(pi.Name, pi.GetCustomAttributes(false));
}
foreach (var expectedSetting in expectedSettings)
{
var invalidValueError = "Config contains an invalid value for " + expectedSetting.Key;
if (!AppSettings.ContainsKey(expectedSetting.Key))
{
error = "Config does not contain " + expectedSetting.Key;
return false;
}
bool isRequired = IsConfigSettingRequired(attrDictionary, expectedSetting);
switch (expectedSetting.Value.FullName)
{
case "System.String":
if (isRequired && String.IsNullOrEmpty(AppSettings[expectedSetting.Key]))
error = invalidValueError;
break;
case "System.Int32":
if (isRequired && !AppSettings[expectedSetting.Key].IsInt32())
error = invalidValueError;
break;
case "System.Int64":
if (isRequired && !AppSettings[expectedSetting.Key].IsInt64())
error = invalidValueError;
break;
case "System.Double":
if (isRequired && !AppSettings[expectedSetting.Key].IsDouble())
error = invalidValueError;
break;
case "System.Boolean":
if (isRequired && !AppSettings[expectedSetting.Key].IsBoolean())
error = invalidValueError;
break;
case "System.DateTime":
if (isRequired && !AppSettings[expectedSetting.Key].IsDateTime())
error = invalidValueError;
break;
}
}
return error == string.Empty;
}
LoadAppSettings
接收您的 AppSettings
类的一个实例,该实例将在您的应用程序中使用,并使用反射来设置属性的值
public void LoadAppSettings(object classInstanceToLoadAppSettingsInto)
{
try
{
var pis = classInstanceToLoadAppSettingsInto.GetType().GetProperties();
foreach (var pi in pis)
{
if (String.IsNullOrEmpty(AppSettings[pi.Name])) continue;
pi.SetValue(classInstanceToLoadAppSettingsInto, Convert.ChangeType(AppSettings[pi.Name], pi.PropertyType, null), null);
}
}
catch (Exception)
{
throw new InvalidOperationException("Failed to load App Settings. Verify .config and class properties.");
}
}
关注点
反射非常棒且功能强大,即使在受限的 .NET 2.0 Compact Framework 中也是如此。
历史