This post contains a couple of topics that came together in a recent update I was making - one a gotcha, and one a solution, that as well as addressing this issue has wider application.
In my web application there was some configuration that consisted of a list of elements. This was represented in code with a POCO like this:
Which can then be injected using IOptions<MySettings> into the classes that need it.
And in configuration, via the appSettings.json file, you can provide the values:
So far so good, but now I wanted to set some default values for this configuration. If nothing is provided, I wanted a non-empty list to be used as the default. But if the user has configured something for the setting, then that should be used.
I figured I could just do the following, setting an initial collection on the class, which would be use unless overridden by a value provided in configuration:
Unfortunately this doesn't work as I expected as was pointed out to me in code review. If for example a single value was configured, it would replace the first value but then the second would still remain. There's a good explanation here of the problem, and why it is actually the expected behaviour.
One solution to this would probably be to change the configuration data structure, to use a dictionary. Unfortunately due to backward compatibility reasons, that wasn't an option in this case.
So I needed a different approach, needing to inpsect the value set from configuration, and depending on what they are, override with some sensible defaults. Which can be done, using PostConfigure. Like most topics with .NET, Andrew Lock has a good blog post explaining this.
The final code looked like this, which, as is needed, will check the configured values and update to the appropriate defaults if necessary:
PostConfigure is a useful technique to have available when you want to make sure configuration provided by users is valid for your application, allowing you to hook into the process, once the configuration has been established but before it is used, to make any necessary updates.
Comments
Post a Comment