5

Let's say I have the following in my config:

<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>

If I want to get either section, I can get them by name pretty easily:

InterestingThingsSection interesting = (InterestingThingsSection)ConfigurationManager.GetSection("interestingThings");
InterestingThingsSection more = (InterestingThingsSection)ConfigurationManager.GetSection("moreInterestingThings");

However, this relies on my code knowing how the section is named in the config - and it could be named anything. What I'd prefer is the ability to pull all sections of type InterestingThingsSection from the config, regardless of name. How can I go about this in a flexible way (so, supports both app configs and web configs)?

EDIT: If you have the Configuration already, getting the actual sections isn't too difficult:

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;
}

However, how do I get the Configuration instance in a generally-applicable way? Or, how do I know if I should use ConfigurationManager or WebConfigurationManager?

zimdanen
  • 5,508
  • 7
  • 44
  • 89

3 Answers3

3

So far, this appears to be the best way:

var config = HostingEnvironment.IsHosted
    ? WebConfigurationManager.OpenWebConfiguration(null) // Web app.
    : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Desktop app.
zimdanen
  • 5,508
  • 7
  • 44
  • 89
  • 1
    A downside to this approach is that HostingEnvironment needs a reference to System.Web.. A more lightweight approach is to use `Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)` as described here: [How determine if application is web application](http://stackoverflow.com/a/3179933) – Svein Fidjestøl Jun 15 '15 at 21:03
1

Try to use ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) method. It opens the configuration file for the current application as a Configuration object.

MSDN documentation: https://msdn.microsoft.com/en-us/library/ms134265%28v=vs.110%29.aspx

Ivan Doroshenko
  • 944
  • 7
  • 13
0

Maybe not the best way to do it but you can read your configuration file as a normal xml and then parse the sections you want. For example if it were a web application:

XmlDocument myConfig= new XmlDocument();
myConfig.Load(Server.MapPath("~/Web.config"));
XmlNode xnodes = myConfig.SelectSingleNode("/configSections");

Now you can see the nodes that you care about discovering the names at runtime and then access the specific node of your configuration file.

Another solution is:

Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)

If this returns "web.config", it is probably a web application.

However, HostingEnvironment.IsHosted is intended to indicate whether an appdomain is configured to run under ASP.NET so it is not sure that yours is a web application.

antferr
  • 100
  • 1
  • 10
  • `Server.MapPath` is web-application-specific, though, right? So I'd still need to know if I have a web or desktop application. If I know that I have one, I can just use `WebConfigurationManager` in that case; what I want is the ability to get the `Configuration` object without knowing if I need to use `WebConfigurationManager` or `ConfigurationManager`. Having the `Configuration` object allows me to use the strongly-typed sections I've already defined rather than parse the XML directly. – zimdanen Jun 10 '15 at 14:57