danielwertheim

danielwertheim


notes from a passionate developer

Developer that lives by the mantra "code is meant to be shared".

Share


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

AppSettings.json, an unfortunate name?

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…

Daniel WertheimDaniel Wertheim

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:

appsettings-build-warnings

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

Developer that lives by the mantra "code is meant to be shared".

View Comments