I'm currently working on a project that consists of a bunch of services. There are two different flavors: either windows services built in .NET Core; or ASP.NET Core based APIs. One thing they all have in common is the use of "appsettings", what they don't have is:
appsettings.json
appsettings.[environment].json
appsettings.local.json
What's the issue?
The problem with generic and common naming like: "appsettings.json"
; is the inherent risk of mixing them up between services. Even higher if the services are located in the same repository and deployed to the same targets. Obviously these are risks that could easily be mitigated by using separate repos and separate deploy targets. But I don't think that is enough.
Be explicit instead
I do believe a simple and effective risk mitigation is to be explicit about the naming. In my case, all services uses a common ServiceRuntimeBuilder
which constructs explicit service names that in turned is used to e.g. bootstrap the configuration from explicit appsettings:
[servicename].settings.json
[servicename].settings.[environment].json;
[servicename].settings.local.json
My ServiceRuntimeBuilder
configures the configuration builder something like this:
var builder = new ConfigurationBuilder()
.AddJsonFile($"{serviceName}.json", optional: true, reloadOnChange: false)
.AddJsonFile($"{serviceName}.{environment}.json", optional: true, reloadOnChange: false)
.AddJsonFile($"{serviceName}.local.json", optional: true, reloadOnChange: false);
Warn or generate an error
I actually do believe MSBuild
should produce a build warning if there's a file called something like:
appsettings.json
appsettings.[environment].json
To accomplish this, all that is missing is in the csproj
file is:
<Target BeforeTargets="Build" Name="EnforceAppSettingsName">
<ItemGroup>
<AppSettingsFiles
Include="$(MSBuildProjectDirectory)\**\appsettings.json;$(MSBuildProjectDirectory)\**\appsettings.*.json;" />
</ItemGroup>
<Warning
Condition="Exists(@(AppSettingsFiles))"
Text="Do not use generic names like: 'AppSettings.json'. Be explicit instead, e.g. '$(AssemblyName).settings.json'." />
</Target>
Results in:
If you are like me, you believe that we ALL should treat build warnings as build errors, hence if a build warning that we haven't explicitly "muted" exists, the build should fail. But if you don't share that philosophy but want the build to fail on the issue above, just change <Warning />
to <Error />
.
That's all for now. As always. You can agree or disagree.
Cheers,
//Daniel