Placeholder Provider
The Placeholder resolver enables usage of ${....}
placeholders in your configuration. The provider enables you to define configuration values as placeholders in your configuration and have them resolved to real
values at runtime during configuration access.
A placeholders takes the form of ${key:subkey1:subkey2?default_value}
where key:subkey1:subkey2
represents another key in the configuration. At runtime when you access the key associated with the placeholder the resolver is called to resolve the placeholder key to a value that exists in the configuration. If a value for the placeholder key is not found, the key will be returned unresolved. If a default_value
is specified in the placeholder, then the default_value
will returned instead.
Note that placeholder defaults (for example, default_value
) can be defined to be placeholders as well and those will be resolved as well.
The Placeholder resolver provider supports the following .NET application types:
- ASP.NET (MVC, WebForms, WebAPI, WCF)
- ASP.NET Core
- Console apps (.NET Framework and .NET Core)
Usage
You should have a good understanding of how the .NET Configuration services work before starting to use this provider.
In order to use the Steeltoe Placeholder resolver provider you need to do the following:
- Add a NuGet package reference to your project.
- Add the provider to the Configuration Builder.
- Optionally, configure Options classes by binding configuration data to the classes.
- Inject and use the Options classes or access configuration data directly.
NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the other samples for example code you can use.
Add NuGet Reference
To use the provider, you need to add a reference to the appropriate Steeltoe NuGet based on the type of the application you are building and what Dependency Injector you have chosen, if any. The following table describes the available packages:
App Type | Package | Description |
---|---|---|
Console/ASP.NET 4.x | Steeltoe.Extensions.Configuration.PlaceholderBase |
Base functionality. No dependency injection. |
ASP.NET Core | Steeltoe.Extensions.Configuration.PlaceholderCore |
Includes base. Adds ASP.NET Core dependency injection. |
To add this type of NuGet to your project, add a PackageReference
resembling the following:
<ItemGroup>
...
<PackageReference Include="Steeltoe.Extensions.Configuration.PlaceholderCore" Version="2.5.2" />
...
</ItemGroup>
Add Configuration Provider
In order to have placeholders resolved when accessing your configuration data, you need to add the Placeholder resolver provider to the ConfigurationBuilder
.
There are four different ways in which you can do this.
- Add the resolver using
ConfigurationBuilder
extension methodAddPlaceholderResolver()
. - Add the resolver to an already built configuration using
IConfiguration
extension methodAddPlaceholderResolver()
. - Add the resolver using
IWebHostBuilder
extension methodAddPlaceholderResolver()
. - Use the
ConfigurePlaceholderResolver()
inConfigureServices()
to add the resolver to the already builtIConfiguration
and to replace it in the container.
The following example shows how to add to the ConfigurationBuilder
:
using Steeltoe.Extensions.Configuration.Placeholder;
...
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
// Add Placeholder resolver
.AddPlaceholderResolver();
Configuration = builder.Build();
...
Extensions are also provided for quick addition to both IHostBuilder
and IWebHostBuilder
. Their usage is identical - the following example shows how to add to the IWebHostBuilder
:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseCloudFoundryHosting()
.AddPlaceholderResolver()
.UseStartup<Startup>()
.Build();
}
NOTE: It is important to understand that the Placeholder resolver works by wrapping and replacing the existing configuration providers already added to the
ConfigurationBuilder
. As a result you typically will want to add it as the last provider.
Access Configuration Data
Once the configuration has been built, the Placeholder resolver will be used to resolve any placeholders as you access your configuration data. Simply access the configuration data as your normally would and the resolver will attempt to resolve and placeholder before returning the value for the key requested.
Consider the following appsettings.json
file:
{
"spring": {
"bar": {
"name": "myName"
},
"cloud": {
"config": {
"name" : "${spring:bar:name?no_name}",
}
}
}
...
}
When using the normal IConfiguration
indexer to access the configuration you will see the Placeholder resolver do its thing:
var config = builder.Build();
Assert.Equal("myName", config["spring:cloud:config:name"]);
...
Access Configuration Data as Options
Alternatively, instead of accessing the configuration data directly from the configuration, you can also use the .NET Options framework together with placeholders.
First, consider the following appsettings.json
and appsettings.Development.json
files:
// appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ResolvedPlaceholderFromEnvVariables": "${PATH?NotFound}",
"UnresolvedPlaceholder": "${SomKeyNotFound?NotFound}",
"ResolvedPlaceholderFromJson": "${Logging:LogLevel:System?${Logging:LogLevel:Default?NotFound}}"
}
// appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
Notice ResolvedPlaceholderFromEnvVariables
uses a placeholder that references the PATH
environment variable which is added to the configuration by the default Web host builder.
Also notice ResolvedPlaceholderFromJson
uses a placeholder that references keys that come from the .json
configuration files.
Next, add the Placeholder resolver to the IWebHostBuilder
in Program.cs
or in any of the other ways described above:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Steeltoe.Extensions.Configuration.PlaceholderCore;
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
// Add Steeltoe Placeholder resolver to apps configuration providers
.AddPlaceholderResolver()
.UseStartup<Startup>();
}
Then to use the configuration and the added Placeholder resolver together with your Options classes simply configure the Options as you normally would.
// Options class
public class SampleOptions
{
public string ResolvedPlaceholderFromEnvVariables { get; set; }
public string UnresolvedPlaceholder { get; set; }
public string ResolvedPlaceholderFromJson { get; set; }
}
// Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// Setup Options framework with DI
services.AddOptions();
// Configure the SampleOptions class with configuration data
services.Configure<SampleOptions>(Configuration);
}
....
}