自定义 AppSettings






4.12/5 (7投票s)
又一篇关于 AppSettings 的文章。
引言
有很多文章讨论 .NET 应用程序的 App.config 文件,无论是控制台应用程序、WinForms 应用程序还是服务,不仅在 CodeProject 上,而且在互联网上随处可见。
它们看起来可能都差不多;但归根结底,没有一篇是完全相同的。这就是为什么我确信本文不会与其他您发现和阅读过的文章相同。谁知道呢,它可能会以某种方式帮助您,甚至更好的是,您可能会获得一些想法并对其进行改进。
我的情况就是如此,我一直在寻找一种自定义、通用的方法来读取我的 App.config,但没有一篇文章说服我,也没有解决我当时的需求,但它们确实给了我关于我想在自己的实现中做什么的好主意。
别人的想法
我从这个开源网站(当然我说的是 CodeProject)上借鉴了两个主要想法。
Paul Haley 在他的 “增强的 AppSettings 配置处理程序” 文章中写道,有时您需要在不同的环境中使用不同的配置来尝试您的应用程序,为此而编辑或注释代码可能会相当烦人。此外,App.config 文件是所有配置都应该存在的地方。(他解释了更多缺点。)
无论如何,他的方法有点更偏向于主机名,如果您想更改这一点,您必须继承他的类并做一些我没费心去读的其他事情。
Diego Mijelshon 有一篇关于 “如何使 AppSettings 与键的多个值一起工作” 的文章。现在,您必须同意我,这也很棒。他明确指出 .NET 有这个严重的缺陷,并且他大致解释了原因。他还展示了如何获取键的多个值,但我认为他使用反射(不是说反射很难)将事情复杂化了一点,原因我不得而知。
我必须指出,这两篇文章都没有问题,它们都能正常工作,但我的需求不同,所以我认为它们会太复杂,事实也确实如此。
背景
当然,建议您了解 appSettings
、System.Configuration.ConfigurationSettings
类、App.config 文件以及编码该文件的 XML。这些主题相当容易,我猜大多数 [.NET] 程序员必须知道或至少听说过它们,对吧?
好了,说完了……我们开始吧!
主要思想
如您可能已经读到的,您可以使用 ConfigurationSettings.AppSettings[...]
获取 App.config 中的简单值,或者可以使用 ConfigurationSettings.GetConfig(string sectionName)
方法创建和读取自定义节,但如果您想自己读取配置文件,则必须创建一个实现 IConfigurationSectionHandler
接口的类,这很容易做到,例如
public class AppSettingHandler : IConfigurationSectionHandler
这样做会迫使您在类中实现一个方法,即 Create(...)
方法,该方法基本上将整个 App.config 文件作为名为 section
的 XmlNode
提供给您。在该方法中,您可以按照您想要的任何方式读取值。
public virtual object Create(object parent, object configContext, XmlNode section)
使用和获取正确的代码
现在,为了让您的主代码自动调用您刚刚实现的 Create(...)
方法,您必须执行以下操作
首先,您的应用程序必须有一个有效且正确的 App.config XML 文件。在其中,您必须包含类似这样的内容,以便可以使用我提供的代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<remove name="appSettings"/>
<section name="appSettings"
type="BellAppSetting.AppSettingHandler, BellAppSetting" />
</configSections>
<appSettings>
<!-- CONFIGURATION GOES HERE-->
</appSettings>
</configuration>
在继续之前,我想指出,没有必要删除 appSettings
节,这只是如果您想将配置放在 <appSettings>
标记内。您可以改为使用类似这样的内容
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="TheNameIwant"
type="BellAppSetting.AppSettingHandler, BellAppSetting" />
</configSections>
<TheNameIwant>
<!-- CONFIGURATION GOES HERE-->
</TheNameIwant>
</configuration>
其次,您必须从主代码调用以下行
ArrayList nvc;
nvc = (ArrayList)ConfigurationSettings.GetConfig("appSettings");
如果您在 App.config 文件中使用了 <remove name="appSettings"/>
,或者
ArrayList nvc;
nvc = (ArrayList)ConfigurationSettings.GetConfig("TheNameIwant");
如果您在 App.config 文件中使用了 <section name="TheNameIwant"
。
您获得的示例
从调用的代码行可以看出,您返回的是一个 ArrayList
。它的结构将在以下示例中显示。如果您需要更多详细信息,请随时下载源代码。
假设您的 App.config 看起来像这样
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<remove name="appSettings"/>
<section name="appSettings"
type="BellAppSetting.AppSettingHandler, BellAppSetting" />
</configSections>
<appSettings>
<Configs use="true">
<add key="ClientConfig" use="true" />
<add key="ServerConfig" use="true"/>
<add key="OtherValue3" use="false"/>
</Configs>
<Configs use="true">
<add key="ClientConfig" use="true" />
<add key="ServerConfig" use="true"/>
<add key="OtherValue3" use="true"/>
<add key="OtherValue4" use="true"/>
</Configs>
<ClientConfig use="true">
<add key="Address2Connect" value="192.168.1.107"/>
<add key="Port2Connect" value="2000"/>
<add key="Log2File" value="Logging.txt"/>
</ClientConfig>
<ClientConfig use="true">
<add key="Address2Connect" value="192.168.1.105"/>
<add key="Port2Connect" value="2000"/>
</ClientConfig>
<ServerConfig use="true">
<add key="PortListenerName" value="2002"/>
<add key="Port2Listen" value="2002"/>
<add key="PortLisFile2Log" value="Logging.txt"/>
</ServerConfig>
<ServerConfig use="false">
<add key="PortListenerName" value="2004"/>
<add key="Port2Listen" value="2004"/>
<add key="PortLisFile2Log" value="Logging.txt"/>
<add key="PortLisLogAll2File" value="false"/>
<add key="GossipSockets" value ="false"/>
<add key="SocketLogAll2IndependantFile" value="false"/>
</ServerConfig>
<OtherValue4 use="true">
<add key="CheckConnections" value="false"/>
<add key="NotifyUserWhenDone" value="true"/>
<add key="OtherConfigValue" value="1"/>
<add key="OtherConfigValue" value="2"/>
</OtherValue4>
</appSettings>
</configuration>
如果您使用示例项目处理此 App.config,您将得到类似这样的结果
最后一些说明
<Configs>
节点用作节集合。- 您可以根据需要放置任意数量的
<Configs>
节点。 - 您可以根据需要放置任意数量的元素节点。
- 您可以看到所有节点都有一个
use
属性,该属性可以接受true
或false
,告诉代码是否要跳过它。 - 每个元素节点都使用
Hashtable
,因此如果您重复它们,它们将被忽略。 - 使用
DictionaryEntry
来允许同一个键有多个值。
关注点
实现自己的 AppSettings
读取器并不像您想象的那么难。当然,这取决于您想做多少,但读取 XmlNode
非常简单明了。您将收到一个包含 Hashtable
、ArrayList
和 DictionaryEntries
的 ArrayList
。我知道这听起来可能很复杂,但搜索它们很容易,并且可以使用 foreach
来完成,就像在示例项目中展示的那样。
如果您 bother to look at the code,它看起来很简单,您不觉得吗?这对我有用,对您也可能有用,所以不妨看看。
总而言之,这可以帮助您为项目使用多个配置,只需通过更改 use
属性值即可打开或关闭它们,您还可以为同一个键插入多个值。
尽情享用!别忘了,任何评论、批评、问题或任何其他反馈都随时欢迎!