Skip to content
This repository has been archived by the owner on Dec 18, 2018. It is now read-only.

Add Exists to IConfigurationSection #292

Closed
poke opened this issue Sep 21, 2015 · 6 comments
Closed

Add Exists to IConfigurationSection #292

poke opened this issue Sep 21, 2015 · 6 comments

Comments

@poke
Copy link

poke commented Sep 21, 2015

Right now, when you get a configuration section using GetSection() there is no simple way to figure out whether that section actually exists. The only thing you could do is check if the value is non-null or if the count of GetChildren() is larger than zero:

IConfigurationSection section = config.GetSection("Some:Section");
bool exists = section.Value != null || section.GetChildren().Count() > 0;

And this doesn’t even work if the section was actually set with a value of null on purpose.

I would like to see some Exists method/property that tells me whether the queried section exists in the configuration. Otherwise, it’s difficult to detect optional configuration parts.


As an example, I want a configuration section Credentials where credentials can be specified. If they are not specified, then that’s fine too. So the configuration may look like this:

"Credentials": {
  "UserName": "username",
  "Password": "password"
}

Or the section may be completely missing. So I get the configuration section using GetSection and now, I want to detect whether that section exists in the configuration or not.

@divega
Copy link

divega commented Sep 21, 2015

Thanks @poke. What would the application do differently if the value of a specific key had been intentionally set to null as opposed to not set at all?

It is perfectly fine for the application to model required configuration settings on top of Configuration (e.g. by throwing exceptions if section.Value == null), however there isn't much of a meaningful difference between something that is not set and something that has intentionally been set to null in our system.

In fact, our configuration sources are not required to be able to represent a null value (in practice, very few can), so an empty string is generally a better representation of a value intentionally left "blank".

Also, I think checking that .Value is not null on specific settings is probably the best way to handle required configuration settings. You can of course look into .GetChildren() to find out about a group of settings under a specific key, but it is hard for me to imagine the scenario in which you want to do both as enough of a common occurrence to justify adding a new API.

@divega divega added this to the Discussions milestone Sep 21, 2015
@poke
Copy link
Author

poke commented Sep 22, 2015

Thanks for the quick reply!

What would the application do differently if the value of a specific key had been intentionally set to null as opposed to not set at all?

That’s a very good question; I guess the answer is that there should be no difference.

The reason I am asking for this is mostly because I want to short-cut logic when a whole configuration tree (/section) does not exist. In my example, I wanted to make the “Credentials” section support different kinds of credentials. So I could first check whether the section exists at all (if not, skip the whole logic), otherwise check whether specific combinations of values exist. And if the section is misconfigured, then I could throw an error that the configuration is wrong; it was specified but is wrong, so the application shouldn’t default to “no credentials”.

So while there is no difference between non-existent and setting it to null, there is a difference between specified with children, and not specified or null.

So maybe, I’m not asking for an Exists but rather a HasChildren that determines if there are entries below the current level.

After all, when I set a value for a section, there are two cases: Setting a value directly (which impacts the Value property), or adding children. Having children invalidates the Value property immediately, because a section cannot have both; since the children collection is the actual value. So I think I should be able to figure out that case without having to peek at GetChildren().

@HaoK
Copy link
Member

HaoK commented Jan 26, 2016

I don't think this statement is true: "Having children invalidates the Value property immediately, because a section cannot have both; since the children collection is the actual value."

@divega
Copy link

divega commented Jan 27, 2016

@HaoK Yes, that is correct: A section can have a value and children at the same time.

Anyway, I can see how having an Exists() method could help. It could either be sugar over section.Value != null || section.GetChildren().Any() or as something slightly less expensive (but that would imply changes to the provider contract).

I will move this to the backlog and track user feedback. We can add it if enough customers want it or if we get a good PR.

@HaoK
Copy link
Member

HaoK commented Nov 21, 2016

bc96e60

@HaoK HaoK closed this as completed Nov 21, 2016
@HaoK HaoK modified the milestones: 1.2.0, Backlog Nov 21, 2016
@RoboBurned
Copy link

I definitely don't like this approach with section.Value != null || section.GetChildren().Any()
It will not work if section exists but is empty.
Example: I have configuration section. And I leave it empty because the corresponding class has default values that I like.

{
  "Authentication": {
    "Development": {
    }
  }
}

public class DevelopmentAuthenticationOptions
{
  public string[] Roles { get; set; }
  public DevelopmentAuthenticationOptions()
  {
    Roles = new[] { "Administrator" };
  }
}

Later, I use

If (Configuration.GetSection("Authentication:Development").Exists())
{
 // Read the section and make required configuration, register services and so on ... 
}

With suggested solution this will not work.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants