通过解析xml文件(app.config)读取应用程序设置的完美解决方案

时间:2019-06-04 16:51:44

标签: c# xml

我正在使用xml阅读器通过一个单独的项目阅读app.config设置。无法通过其他dll中的Properties.Settings.Default.MySetting读取app.config。现在,我试图找到一个合适的解决方案,如何读取不同格式(StringCollection,String等)的不同设置。

https://imgur.com/a/AxeCTsC

(对于所有问我为什么不阅读TestConsole中的信息的人:

            var sc = Properties.Settings.Default.PathToPython;

那是因为我重用了项目。在这种情况下,我有一个TestConsole,我将添加服务应用程序。 TestConsole应用程序仅用于开发。但是我不想将我的代码从一个应用程序复制到另一个应用程序。 TestConsol或更高版本的服务应用程序将获取尽可能少的代码。

app.config的一部分如下所示:

<applicationSettings>
<ToolkitConnector.Ui.TestConsole.Properties.Settings>
  <setting name="PythonApp" serializeAs="String">
    <value>status.py</value>
  </setting>
  <setting name="PathToPython" serializeAs="String">
    <value>python</value>
  </setting>
  <setting name="OutputFolder" serializeAs="String">
    <value>c:\toolkit_1\status\statusOfPlatform1\</value>
  </setting>
  <setting name="PySkriptWorkingDirectory" serializeAs="String">
    <value>c:\toolkit_1\</value>
  </setting>
  <setting name="LgInInformation" serializeAs="Xml">
    <value>
      <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <string>User1</string>
        <string>Pwd1</string>
        <string>GER_PROD</string>
        <string>18701</string>
        <string>Technology1</string>
        <string>User2</string>
        <string>Pwd2</string>
        <string>GER_PROD</string>
        <string>18795</string>
        <string>Technology2</string>
      </ArrayOfString>
    </value>
  </setting>
</ToolkitConnector.Ui.TestConsole.Properties.Settings>

在我的项目Logic.ControlAppSetting中,我使用该代码读取xml文件

        public void GetApplicationSetting(string path)
        {
            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load(path);
                XmlElement root = doc.DocumentElement;
                var applicationSettings = root.SelectSingleNode("applicationSettings");
                var mySettings = applicationSettings.SelectSingleNode("ToolkitConnector.Ui.TestConsole.Properties.Settings");
                foreach (XmlNode node in mySettings)
                {
                    var test = node.Attributes;
                }
            }
            catch { }
        }

现在,我正在寻找一种优雅的解决方案,将设置信息存储在变量中。我的问题是我有不同的类型,例如StringCollection和String。也许有更好的方法来存储此信息?

非常感谢

编辑:

我也尝试过:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            ConfigurationSectionGroup userSettings = config.GetSectionGroup("applicationSettings");
            ClientSettingsSection settings = (ClientSettingsSection)userSettings.Sections.Get("Ui.TestConsole.Properties.Settings");
            SettingElement elem = settings.Settings.Get("LgInInformation");

2 个答案:

答案 0 :(得分:0)

最简单的解决方案是不要让其他库直接依赖于此文件或用于读取其值的自动生成的Settings类。您的库不需要文件或类。它只需要这些值。

如果您的库依赖于读取此文件,则它只能在存在该文件的环境中工作。这将使其难以使用。通常,我们可以只添加对库的引用并使用它。但是,如果库依赖于此文件,那么我们将不得不修改使用该库的应用程序以包括这些设置。

这也将使为库编写单元测试变得困难或不可能。您还必须将所有这些设置添加到单元测试项目中。但是,如果要使用两个不同的设置为库编写测试该怎么办?那会很痛苦的。

相反,请定义一个与环境无关的类,其中确切包含此库所需的设置。

最简单的形式

public class MyLibraryConfigurationSettings
{
    public string PythonApp { get; set; }
    public List<string> LgInInformation { get; } = new List<string>();
}

然后编写您的库,以便使用它,调用应用程序必须提供这些设置。

现在您已经完成了库方面的工作。为了使用它,您必须给它所需的东西。它不知道也不关心这些值的来源。它不知道是否有配置文件,或者在哪里。

现在,您的应用程序必须将其提供给库。为此,可以创建该类的实例,然后使用Properties.Settings.Default.MySetting来填充它。或者它可以以其他方式填充它。现在,您的应用程序也不必使用该文件。


此方法的另一个好处是,它使要求更加明确。例如,您可以创建库,以便将其添加到应用程序中需要提供配置值。例如,许多库提供了用于向IServiceCollection注册自己的扩展名。您可以这样做:

services.AddYourLibrary(MyLibraryConfigurationSettings settings);

很明显,这就是应用程序必须提供的。您可以通过提供可以轻松反序列化的类来简化此操作。

如果您依赖文件,则关系不太清楚。您可以添加对该库的引用,编写一些代码,一切看起来都很好。然后在运行时,它抛出一个异常,指出“文件在哪里?”然后开发人员说:“什么文件?”并且他们必须寻找文档来描述必须如何定义该文件。如果必须使用<applicationSettings>部分创建文件,则将更加复杂。

答案 1 :(得分:-1)

根据您所说的,我认为您在这里过度设计了解决方案。

.Net提供了一个内置库,用于读取其他app.config文件:

var cfg = ConfigurationManager.OpenExeConfiguration(@"path_to_file");

这将返回指定的path_to_file作为已加载的配置,您可以像这样使用:

var setting = cfg.AppSettings["setting_name"];