在UI和服务之间共享配置

时间:2015-06-17 16:53:20

标签: c# winforms

有没有办法在不同的程序集中反序列化user.config?我需要一个绑定到Properties.Settings的表单,然后是一个访问这些设置的服务。

我已尝试ConfigurationManager加载配置正常,但似乎有某种保护使userSettings部分无法覆盖。

到目前为止失败的另一件事是XmlSerializer,我不确定它是否可以映射到配置文件结构。

1 个答案:

答案 0 :(得分:1)

我使用内置的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仍然可以正常工作,但它会将控件序列化为新名称,然后它将破坏您的服务。

它避免了这种紧密耦合,你可以很容易地破坏我将employeeName文本框直接绑定到类似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();

我希望有所帮助。