Contents
1. Introduction
Most of time, we need to publish a .Net Core project to difference environment with corresponding configuration, so we should something config files like below
appsettings.dev.json
appsettings.uat.json
appsettings.demo.json
appsettings.prod.json
by default, .Net program only get the configuration value from appsettings.json
, so how can we read the specified configuration from these files? and how to make sure only one environment configuration file to be copied to the publish folder?
2. What I want to do
There are many tutorials shows you how to use ASPNETCORE_ENVIRONMENT
to handle multiple environments, for this approach you need to define or update ASPNETCORE_ENVIRONMENT
when you launch or publish the project, but I just want to publish the project with a command and don’t need to change anything (including any config files).
Because I want to deploy the project to difference server and don’t want to change their configuration or environment anymore, this can make sure the deployment source code is stable and avoid to update to wrong environment variables.
So I suppose the publish flow should be just executed the publish command and then copy the release folder to server.
3. Setup multiple environments configuration file
For do that, we need to load the specified environment config file with below in Program.cs
builder.Configuration.AddJsonFile('appsettings.dev.json', optional: true, reloadOnChange: true);
and use the precompiled command to load difference items
#if DEV
builder.Configuration.AddJsonFile('appsettings.dev.json', optional: true, reloadOnChange: true);
#elif DEMO
builder.Configuration.AddJsonFile('appsettings.demo.json', optional: true, reloadOnChange: true);
#elif UAT
builder.Configuration.AddJsonFile('appsettings.uat.json', optional: true, reloadOnChange: true);
#elif PROD
builder.Configuration.AddJsonFile('appsettings.prod.json', optional: true, reloadOnChange: true);
#endif
but wait, for using these precompiled constants, we need to define the constants in the project *.csproj
file
<PropertyGroup Condition=" '(Configuration)' == 'demo'">
<DefineConstants>DEMO</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '(Configuration)' == 'dev'">
<DefineConstants>DEV</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '(Configuration)' == 'uat'">
<DefineConstants>UAT</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '(Configuration)' == 'prod'">
<DefineConstants>PROD</DefineConstants>
</PropertyGroup>
We can define custom constant base on the condition, and the $(Configuration)
value is passed from the build command (I will show you later).
In this case, we will find several appsettings files(all environments file) in publish folder, but we should only need one file for current environment, so we need to continue to add below code in *.csproj
file
<ItemGroup Condition=" '(Configuration)' == 'dev'">
<Content Remove="appsettings.demo.json" />
<Content Remove="appsettings.uat.json" />
<Content Remove="appsettings.prod.json" />
</ItemGroup>
<ItemGroup Condition=" '(Configuration)' == 'demo'">
<Content Remove="appsettings.dev.json" />
<Content Remove="appsettings.uat.json" />
<Content Remove="appsettings.prod.json" />
</ItemGroup>
<ItemGroup Condition=" '(Configuration)' == 'uat'">
<Content Remove="appsettings.demo.json" />
<Content Remove="appsettings.dev.json" />
<Content Remove="appsettings.prod.json" />
</ItemGroup>
<ItemGroup Condition=" '(Configuration)' == 'prod'">
<Content Remove="appsettings.demo.json" />
<Content Remove="appsettings.dev.json" />
<Content Remove="appsettings.uat.json" />
</ItemGroup>
As you see, we will remove other useless appsettings file base on the condition, so it will only copy the current environment config file to publish folder.
Ok, finally, we can use below command to publish the project base on difference environment
dotnet publish -c demo -r win-x64 -p:PublishReadyToRun=true
The main point here is -c
parameter, this is the $(Configuration)
what we use in csproj
file.
For example, the above command will only generate below config files in publish folder
appsettings.json
appsettings.demo.json
4. Conclusion
We should use multiple environments configuration for our project, we can simple to use a flag in appsettings.json
for that, for example evn:uat
, but in this case, we need to change the appsettings.json
every time when publish the project, and also need to handle more logic in the source code, to avoid to update the wrong settings in other environments, I suggest to use a publish command for handle difference environment, after executed the command, then will generate the source code to corresponding publish folder, and then we just need to copy these file to server.