A demonstration of how to embed JSON configuration files from one .NET project and use them in another, with the ability to override values in the consuming project.
This solution demonstrates a pattern for sharing configuration settings across multiple .NET projects by embedding configuration files as resources in a shared library project and then consuming them in other projects. The key feature is that the consuming projects can override specific values while inheriting the rest.
The solution consists of three projects:
- Sample.Extensions.Configuration.Embedded - The core library that provides the functionality to load embedded JSON configuration files.
- ExampleConfigurationProject - A library project that embeds configuration files and provides extension methods to use them.
- ExampleConsole - A console application that demonstrates how to use the embedded configuration and override values.
The ExampleConfigurationProject
embeds its appsettings.json
and appsettings.Development.json
files as embedded resources:
<ItemGroup>
<EmbeddedResource Include="appsettings.json" />
<EmbeddedResource Include="appsettings.Development.json" />
</ItemGroup>
The Sample.Extensions.Configuration.Embedded
library provides extension methods to load these embedded resources into the .NET configuration system:
AddEmbeddedJsonFile
- Adds an embedded JSON file to the configurationAddEmbeddedJsonFileAtIndex
- Adds an embedded JSON file at a specific index in the configuration sources
The key feature is the ability to control the precedence of configuration sources. The embedded configuration files are inserted at specific positions in the configuration source chain:
- The embedded
appsettings.json
is inserted before the consuming project'sappsettings.json
- The embedded
appsettings.Development.json
is inserted before the consuming project'sappsettings.Development.json
In .NET configuration, sources added later override earlier ones. This means the consuming project's settings will override the embedded settings, allowing applications to inherit default values from the library while customizing specific settings as needed.
Lower Priority
┌─────────────────────────────────────┐
│ Command Line Arguments │
├─────────────────────────────────────┤
│ Environment Variables │
├─────────────────────────────────────┤
│ User Secrets (Development) │
├─────────────────────────────────────┤
│ Embedded appsettings.json │ <- Library's embedded default settings
├─────────────────────────────────────┤
│ appsettings.json │ <- Consuming project's default settings
├─────────────────────────────────────┤
│ Embedded appsettings.{Environment} │ <- Library's embedded environment-specific settings
├─────────────────────────────────────┤
│ appsettings.{Environment}.json │ <- Consuming project's environment-specific settings
└─────────────────────────────────────┘
Higher Priority (overrides lower)
- Add your configuration files as embedded resources:
<ItemGroup>
<EmbeddedResource Include="appsettings.json" />
<EmbeddedResource Include="appsettings.Development.json" />
</ItemGroup>
-
Reference the
Sample.Extensions.Configuration.Embedded
library -
Create extension methods to add your embedded configuration:
public static class ConfigurationSettingsExtensions
{
public static IConfigurationBuilder AddSharedSettings(this IConfigurationBuilder builder,
string environmentName,
bool optional = false)
{
var assembly = Assembly.GetExecutingAssembly();
var name = assembly.GetName();
// Add the primary embedded settings before the standard appsettings.json
// This allows the standard settings to override the embedded ones
var index = builder.FindStandardJsonSource();
builder.AddEmbeddedJsonFileAtIndex(
assembly,
$"{name.Name}.appsettings.json",
index ?? 0,
optional);
// Add the environment specific embedded settings before the environment-specific standard settings
index = builder.FindStandardJsonSource(environmentName);
builder.AddEmbeddedJsonFileAtIndex(
assembly,
$"{name.Name}.appsettings.{environmentName}.json",
index ?? 1,
optional);
return builder;
}
public static TBuilder UseSharedSettings<TBuilder>(this TBuilder builder, bool optional = false)
where TBuilder : IHostApplicationBuilder
{
builder.Configuration.AddSharedSettings(builder.Environment.EnvironmentName, optional);
return builder;
}
}
- Add your own configuration files:
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
-
Reference your library project
-
Use the extension method to add the embedded configuration:
var host = Host.CreateApplicationBuilder(args)
.UseSharedSettings()
.Build();
- Centralized Configuration: Maintain common configuration in a single place
- Flexibility: Override specific values in consuming projects
- Environment Support: Works with different environments (Development, Production, etc.)
- Standard .NET Configuration: Integrates with the standard .NET configuration system
This project is licensed under the MIT License - see the LICENSE file for details.