Appsettings and Environments
In .NET core and newer the old app.config as XML file gets replaced by the appsettings.<environment>
.json file to store settings, like logger configurations, connectionstrings and more. The <environment>
part can determine for which scenario the file gets loaded. You could write “Production”, or “development” files to load different settings for the application.
Setup
Files
You can add this file via VS context menu and choose the JavaScript-JSON-Configuration file. Change the properties of the file to “always copy” or to “copy if newer” to place it in the build directory. You can also change this in the project file:
If you have a different appsettings file for debug purposes you can control if it will be copied to the output directory with the project settings, too.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Choose>
<When Condition="'$(Configuration)' == 'Debug'">
<ItemGroup>
<None Include="appsettings.json"
CopyToOutputDirectory="Always"
CopyToPublishDirectory="Always" />
<None Include="appsettings.Development.json"
CopyToOutputDirectory="Always"
CopyToPublishDirectory="Always" />
</ItemGroup>
</When>
<When Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<None Include="appsettings.json"
CopyToOutputDirectory="Always"
CopyToPublishDirectory="Always" />
<None Include="appsettings.Development.json"
CopyToOutputDirectory="Never"
CopyToPublishDirectory="Never" />
</ItemGroup>
</When>
</Choose>
The conditions control the copy process via debug or release settings.
You can set a dependency of the two files to show them in a hierarchy in the project structure:
1
2
3
4
5
<ItemGroup>
<None Update="appsettings.Development.json">
<DependentUpon>appsettings.json</DependentUpon>
</None>
</ItemGroup>
Environment Variables
Create the file Properties\LaunchSettings.json and write the following entries to activate the Development environment variable:
1
2
3
4
5
6
7
8
9
10
{
"profiles": {
"YOUR_PROJECT_NAME": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
You can also set this up via UI in VS:
Configuration and host builder
Create the configuration variable from the appsettings file[s]:
1
2
3
4
5
6
// Build a configuration from appsettings.json files and store them in the var
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", true)
.Build();
This examples also uses the environment variable DOTNET_ENVIRONMENT
which should be set for each mode you are working with. If you switch to release this does not throw an exception for a missing file, because the call for .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", true)
uses true as flag for optional.
use with serilog logging
If you use serilog you can use the different file for debug and release as well. This also enables logging even before setting up the Host Builder for further setups.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Create logger with above configuration
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.WithMachineName()
.Enrich.WithProcessName()
.Enrich.WithThreadId()
.Enrich.WithAssemblyVersion()
.WriteTo.MSSqlServer(
//connectionString: ConnectionStringBuilder.GetFromConfigOrDefault(configuration),
connectionString: configuration.GetConnectionString("LogConnectionString"),
new MSSqlServerSinkOptions
{
SchemaName = SchemaName,
TableName = TableName,
AutoCreateSqlTable = true
},
columnOptions: BuildColumnOptions())
.CreateLogger();
Host builder with serilog
Now you only have to build the host with the serilog integration and register your DI services:
1
2
3
4
5
6
7
8
9
// Build host with Dependency Injection and Serilog as logger
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// define DI here ...
services.AddTransient<IYourService, YourService>();
})
.UseSerilog() // <- Serilog
.Build();