C# 如何获取特定类型的所有节

C# 如何获取特定类型的所有节,c#,configuration,C#,Configuration,假设我的配置中有以下内容: <configSections> <section name="interestingThings" type="Test.InterestingThingsSection, Test" /> <section name="moreInterestingThings" type="Test.InterestingThingsSection, Test" /> </configSections> <inte

假设我的配置中有以下内容:

<configSections>
  <section name="interestingThings" type="Test.InterestingThingsSection, Test" />
  <section name="moreInterestingThings" type="Test.InterestingThingsSection, Test" />
</configSections>

<interestingThings>
  <add name="Thing1" value="Seuss" />
</interestingThings>

<moreInterestingThings>
  <add name="Thing2" value="Seuss" />
</moreInterestingThings>
然而,这依赖于我的代码知道该节在配置中是如何命名的——它可以被命名为任何名称。我更喜欢的是能够从配置中提取类型为
InterestingThingsSection
的所有部分,而不管名称如何。如何以灵活的方式实现这一点(因此,支持应用程序配置和web配置)

编辑:如果您已经有了
配置
,获取实际部分并不太困难:

public static IEnumerable<T> SectionsOfType<T>(this Configuration configuration)
    where T : ConfigurationSection
{
    return configuration.Sections.OfType<T>().Union(
        configuration.SectionGroups.SectionsOfType<T>());
}

public static IEnumerable<T> SectionsOfType<T>(this ConfigurationSectionGroupCollection collection)
    where T : ConfigurationSection
{
    var sections = new List<T>();
    foreach (ConfigurationSectionGroup group in collection)
    {
        sections.AddRange(group.Sections.OfType<T>());
        sections.AddRange(group.SectionGroups.SectionsOfType<T>());
    }
    return sections;
}
public static IEnumerable SectionsOfType(此配置)
其中T:ConfigurationSection
{
返回configuration.Sections.OfType().Union(
configuration.SectionGroups.SectionsOfType());
}
公共静态IEnumerable SectionSoftType(此配置SectionGroupCollection集合)
其中T:ConfigurationSection
{
var sections=新列表();
foreach(集合中的ConfigurationSectionGroup组)
{
sections.AddRange(group.sections.OfType());
sections.AddRange(group.SectionGroups.SectionsOfType());
}
回流段;
}

但是,如何以普遍适用的方式获取
配置
实例?或者,我如何知道是否应该使用
ConfigurationManager
WebConfigurationManager

也许不是最好的方法,但您可以将配置文件作为普通xml读取,然后解析所需的部分。例如,如果它是一个web应用程序:

XmlDocument myConfig= new XmlDocument();
myConfig.Load(Server.MapPath("~/Web.config"));
XmlNode xnodes = myConfig.SelectSingleNode("/configSections");
现在,您可以看到在运行时查找名称所关心的节点,然后访问配置文件的特定节点

另一个解决办法是:

Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
如果返回“web.config”,则可能是一个web应用程序


但是,HostingEnvironment.IsHosted用于指示是否将appdomain配置为在ASP.NET下运行,因此无法确定您的应用程序是否为web应用程序。

尝试使用
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
方法。它将当前应用程序的配置文件作为
配置
对象打开


MSDN文档:到目前为止,这似乎是最好的方法:

var config = HostingEnvironment.IsHosted
    ? WebConfigurationManager.OpenWebConfiguration(null) // Web app.
    : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Desktop app.

Server.MapPath
是特定于web应用程序的,对吗?所以我仍然需要知道我是否有一个web或桌面应用程序。如果我知道我有一个,我可以在这种情况下使用
WebConfigurationManager
;我想要的是能够在不知道是否需要使用
WebConfigurationManager
ConfigurationManager
的情况下获取
ConfigurationManager
对象。拥有
配置
对象允许我使用我已经定义的强类型部分,而不是直接解析XML。这种方法的一个缺点是HostingEnvironment需要对System.Web的引用。。更轻量级的方法是使用
Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
,如下所述:
var config = HostingEnvironment.IsHosted
    ? WebConfigurationManager.OpenWebConfiguration(null) // Web app.
    : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Desktop app.