如何获取特定类型的所有部分

5

假设我在配置文件中有以下内容:

<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 interesting = (InterestingThingsSection)ConfigurationManager.GetSection("interestingThings");
InterestingThingsSection more = (InterestingThingsSection)ConfigurationManager.GetSection("moreInterestingThings");

然而,这取决于我的代码知道配置中部分的名称 - 它可以被命名为任何内容。我更喜欢的是从配置中提取所有类型为InterestingThingsSection的部分,而不考虑名称。我该如何以灵活的方式实现这一点(因此,支持应用程序配置和Web配置)?
编辑:如果您已经有了Configuration,获取实际的部分并不太困难:
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;
}

然而,我该如何以一种普遍适用的方式获取Configuration实例呢?或者说,我该如何知道是应该使用ConfigurationManager还是WebConfigurationManager呢?

3个回答

3
到目前为止,这似乎是最好的方法:
var config = HostingEnvironment.IsHosted
    ? WebConfigurationManager.OpenWebConfiguration(null) // Web app.
    : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Desktop app.

1
这种方法的缺点是HostingEnvironment需要引用System.Web。一种更轻量级的方法是使用Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile),如此处所述:如何确定应用程序是否为Web应用程序 - Svein Fidjestøl

1

0
也许这不是最好的方法,但您可以像普通的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 旨在指示应用程序域是否配置为在 ASP.NET 下运行,因此不能确定您的应用程序是 Web 应用程序。

Server.MapPath 是特定于 Web 应用程序的,对吗?那么我仍然需要知道我是在使用 Web 还是桌面应用程序。如果我知道我在使用哪个,就可以在那种情况下使用 WebConfigurationManager;我想要的是能够获取 Configuration 对象的能力,而不需要知道我是否需要使用 WebConfigurationManagerConfigurationManager。拥有 Configuration 对象允许我使用已经定义的强类型部分,而不是直接解析 XML。 - zimdanen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接