【发布时间】:2015-09-03 01:17:05
【问题描述】:
有没有办法在不同的程序集中反序列化user.config?我需要一个绑定到Properties.Settings 的表单,然后是一个访问这些设置的服务。
我试过ConfigurationManager 可以很好地加载配置,但似乎有某种保护措施使userSettings 部分无法触及。
到目前为止失败的另一件事是XmlSerializer,我不确定它是否可以映射到配置文件结构。
【问题讨论】:
有没有办法在不同的程序集中反序列化user.config?我需要一个绑定到Properties.Settings 的表单,然后是一个访问这些设置的服务。
我试过ConfigurationManager 可以很好地加载配置,但似乎有某种保护措施使userSettings 部分无法触及。
到目前为止失败的另一件事是XmlSerializer,我不确定它是否可以映射到配置文件结构。
【问题讨论】:
我使用过类似使用内置 XmlTextReader 读取 user.config 文件的方法。
但我还要说,使用文本文件将您的服务和 UI 耦合起来似乎是一个糟糕的设计,尤其是用户配置文件,考虑到该文件很容易被意外值填充(例如,用户可能输入错误错误的值,然后关闭 UI,将错误的值留在配置文件中)。
如果你能告诉我更多关于你的应用程序的信息,我可以推荐一个更好的方法。
XmlTextReader reader = new XmlTextReader(filename);
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Text:
switch (settingKey) //Do something
{
更新:
您的方法的问题在于它违反了“关注点分离”的原则,因为更改您的 UI 将更改您的模型(在 UI 应用程序上),这将与您的服务上的模型不同步。这是 user.config 的工作方式,因为它通常不用于存储应用程序之间共享的数据(这就是通常使用配置文件的方式),因此它在幕后发挥了一些魔力,使其易于设置。
这就是我的做法。
假设您有一个名为 Employee 的模型: (借用here的代码)
[XmlRoot("employee")]
public class EmployeesModel
{
[Required]
[DisplayName("Name: ")]
[XmlElement("employeeName")]
public string employeeName { get; set; }
[Required]
[DisplayName("Position: ")]
[XmlElement("employeePosition")]
public string employeePosition { get; set; }
//etc
}
您可以使用以下方式将您的 XML 反序列化为该模型的新实例:
var serializer = new XmlSerializer(typeof(EmployeesModel));
employee anEmployee =
from xml in xmlDoc.Descendants("employee")
select serializer.Deserialize(xml.CreateReader()) as EmployeesModel;
现在在您的服务中,您可以使用 XML 中的 EmployeesModel 实例。
在您的 GUI 中,您可以非常小心地使用与模型相同的字段名称,以便您的 user.config XML 与您的模型匹配。例如。如果您在 GUI 中更改“employeeName”文本框,那么您的 GUI 仍然可以正常工作,但它会将控件序列化为新名称,然后会中断您的服务。
它避免了这种紧密耦合,在这种情况下您可以轻松破坏事物,我会将您的员工姓名文本框直接绑定到模型,执行类似 this using INotifyPropertyChanged 的操作。数据绑定非常复杂,因此您可能需要阅读它here。
这就是为什么您不能在弄乱 UI 时无意中更改模型的原因,因为 UI 将不再正确绑定并且您会收到编译错误。
然后您仍然需要序列化您的控件(例如,当您的 UI 关闭时),但这很容易,因为这些文本框和其他控件已绑定到模型。所以你所要做的就是:
XmlSerializer xmlserializer = new XmlSerializer(EmployeesModel);
StringWriter stringWriter = new StringWriter();
XmlWriter writer = XmlWriter.Create(stringWriter);
xmlserializer.Serialize(writer, anEmployee); //this is your model instance from above
serializeXml = stringWriter.ToString();
writer.Close();
希望对你有帮助。
【讨论】:
INotifyPropertyChanged,自定义数据绑定也很有用,这使得它在生产力方面也可以与内置设置竞争。