Giter Club home page Giter Club logo

notmicrosoft.configuration's Introduction

NotMicrosoft.Configuration

Build status - Windows Build

Build Status - Linux

NuGet Coverage Status

Extending the configuration posibilities of .NET core apps via json by using configurable "variables" (e.g. $connection_string$) whose values are stored in ini/properties files (e.g. making it a better solution for deploying production apps :)). Fully compatible with the built-in json configuration provider - designed to work as a drop-in replacement for it.

Background

Microsoft introduced with .NET Core the Configuration API as a way of configuring an application. An application configuration must have an easy way of changing it depending on the environment (qa, staging, production, whatever) where the application is running.

This new way of configuring an application is way better and more flexible than the older ways (for example web.config and the horrible transformation file - horrible even if you love xml & its children :) - but this probably deserves its own rant), but it still has gaps and is unnecessary messy to achieve some simple changes - which is surprising considering that this is easy on other platforms (e.g. for example in java spring & properties files)

The problem

Considering the example of configuring Serilog in appsettings.json file and the fact that we want to overwrite this configuration when running in production - we want to overwrite the MinimumLevel and the path where the log files will be stored (this is quite expected and in fact exactly what is asked on stack overflow in one of the questions - http://stackoverflow.com/questions/37657320/how-to-override-an-asp-net-core-configuration-array-setting-using-environment-va)

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Literate" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      { "Name": "LiterateConsole" },
      { "Name": "Trace" },
      {
        "Name": "RollingFile",
        "Args": {
          "pathFormat": "./Log/Log-{Date}.txt",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {MachineName} {RequestId} ({ThreadId}) [{Level}] - {Message}{NewLine}{Exception}"
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  }
}

Using Microsoft configuration api, there are couple of options for this (as far as I know):

  • Create appsettings.envname.json and repeat the WHOLE!!! Serilog json block again with the new values for MinimumLevel and pathFormat - this is probably the worst thing you can do
  • Overwrite via ini file or environment variable by using the configuration hierarchy (this is what is suggested in the answer to the stack overflow question) e.g.
    • Serilog:MinimumLevel=Information
    • Serilog:WriteTo:0:Args:pathFormat={some other path}

Now, this is better than the json overwrite but still too messy:

  • this json block is very often represented in code by some type and the json is mapped automatically to the type. Any change in that type structure needs to be reflected in changes in appsettings.json (and this is probably expected by the dev team), but in our case will trigger changes in environment specific files/config (ini file and/or environment variables). These files are possible owned by other teams (production configuration values). So a change in the configuration type can trigger a chain reaction. Now, you can "template" the ini files and create some other configuration names which are the environment specific ones (anything can be solved with another level of indirection :), isn't it) - but why complicate yourself.
  • could look just like random crap e.g. Serilog:WriteTo:0:Args:pathFormat - how this makes sense? :)
  • if you just want to just partially configure a value - this is not possible. For example, if we have a connection string and we just want to modify the password for the database user (as all the other values are the same between environments). This is not possible using the configuration api and the whole connection string needs to be set together with the new password.

The solution

New json configuration provider which makes appsettings.json to work as a template whose "variables" are replaced via name-values pairs from a ini file. For example, the Serilog configuration will look like this

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Literate" ],
    "MinimumLevel": "$log_level$",
    "WriteTo": [
      { "Name": "LiterateConsole" },
      { "Name": "Trace" },
      {
        "Name": "RollingFile",
        "Args": {
          "pathFormat": "$log_path$",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {MachineName} {RequestId} ({ThreadId}) [{Level}] - {Message}{NewLine}{Exception}"
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  }
}

Underneath the provider is using StringTemplate to do the replacements. I would have prefereed to use the spring syntax ${var}, but this is not supported by StringTemplate.

See sample for basic usage.

notmicrosoft.configuration's People

Contributors

dsbenghe avatar darkosancanin avatar

Watchers

Jose Fajardo avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.