【发布时间】:2015-07-11 02:25:53
【问题描述】:
我有一个可以连接到多个服务器的应用程序。服务器的实际数量直到运行时才知道,并且可能每天都在变化。完全定义一个服务器需要几个实际参数。
我正在尝试使用对应用程序配置的 .NET 支持来配置应用程序。
配置文件类似于:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup
name="userSettings"
type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="server"
type="System.Configuration.SingleTagSectionHandler"
allowExeDefinition="MachineToLocalUser"
requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<server name="washington">
<add name="host" value="abc.presidents.com"/>
<add name="port" value="1414"/>
<add name="credentials" value="george"/>
</server>
<server name="adams">
<add name="host" value="def.presidents.com"/>
<add name="port" value="1419"/>
<add name="credentials" value="john"/>
</server>
<!--insert more server definitions here -->
</userSettings>
</configuration>
我尝试使用类似这样的代码阅读此内容(WriteLines 用于诊断问题。当/如果它有效时它们会消失。):
try
{
var exeConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
Console.WriteLine(exeConfiguration);
var userSettings = exeConfiguration.GetSectionGroup("userSettings");
Console.WriteLine("{0}: {1}", userSettings, userSettings.Name);
var sections = userSettings.Sections;
Console.WriteLine("{0}: {1}", sections, sections.Count);
foreach (ConfigurationSection section in sections)
{
Console.WriteLine("{0}", section);
// todo Here's where we capture information about a server
}
}
catch (System.Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}
这会从 foreach 中引发异常并产生以下输出:
System.Configuration.Configuration
System.Configuration.UserSettingsGroup: userSettings
System.Configuration.ConfigurationSectionCollection: 1
Exception: Sections must only appear once per config file. See the help topic <location> for exceptions.
如果我删除第二台服务器,只留下华盛顿,它会“工作”产生以下输出:
System.Configuration.Configuration
System.Configuration.ConfigurationSectionGroup: userSettings
System.Configuration.ConfigurationSectionCollection: 1
System.Configuration.DefaultSection
我已经尝试了该主题的其他变体(嵌套 sectionGroups 等),但没有找到解决方案。我发现的各种教程示例似乎希望我为每个服务器创建一个单独的类。这显然是不切实际的,而且应该是不必要的,因为所有服务器都是平等的。
问题:
- System.Configuration 是否支持相关设置集合的概念(如结构数组)?
- 如果是这样.. 怎么办?
- 如果没有.. 是否有另一种方法来存储支持此概念的持久配置信息,还是我必须自己动手?
进度报告
根据 Robert McKee 的部分回答,我修改了 xml,如下所示:
<section name="servers"
type="System.Configuration.DefaultSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
和
<servers>
<add name="washington" host="abc.presidents.com" port="1414" credentials="george"/>
<add name="adams" host="def.presidents.com" port="1419" credentials="john"/>
<!--insert more server definitions here -->
</servers>
这是一个致命问题的改进。如您所见,我将section元素的type属性更改为将类命名为ystem.Configuration.DefaultSectionDefaultSection成功读取配置信息(我认为,至少它不会抱怨。)但它没有暴露任何方式来访问它读取的信息!
因此我需要使用其他类型的*Section 类。 Microsoft 提供了从 ConfigurationSection 基类派生的 95 个类,但除 DefaultSection 和 ClientSettingsSection 之外的所有类似乎都针对特殊情况(url、数据库连接字符串、日期和时间等)@987654335 @ 甚至不会阅读服务器部分——抱怨 <add/> 不是有效的嵌套元素。
所以,底线是我将不得不编写一个自定义ConfigurationSection 来处理这些设置。如果我得到它的工作,我会添加一个最终解决方案的答案(除非有人首先提供更好的答案。)
【问题讨论】:
标签: c# .net configuration