Stronk 5.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Stronk --version 5.3.0                
NuGet\Install-Package Stronk -Version 5.3.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Stronk" Version="5.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Stronk --version 5.3.0                
#r "nuget: Stronk, 5.3.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Stronk as a Cake Addin
#addin nuget:?package=Stronk&version=5.3.0

// Install Stronk as a Cake Tool
#tool nuget:?package=Stronk&version=5.3.0                

Stronk

Mapping app.config an web.config to strong typed objects

Installation

PM> install-package Stronk

Usage

public class Startup
{
    public void Configure(IAppBuilder app)
    {
        var config = new StronkConfig()
            .Build<MyApplicationConfiguration>();
        // ...
    }
}

public class MyApplicationConfiguration
{
    public string ApplicationName { get; private set; }
    public int ApiVersion { get; private set; }
    public ConfigurationMode Mode { get: private set; }

    public string MainDB { get; set; }
}

public enum ConfigurationMode
{
    Local,
    Dev,
    Test,
    QA,
    ExternalTest,
    Production
}

App.Config or Web.Config

<configuration>
  <appSettings>
    <add key="ApplicationName" value="testing" />
    <add key="ApiVersion" value="12" />
    <add key="Mode" value="QA" />
  </appSettings>
  <connectionStrings>
    <add name="MainDb" connectionString="Some Connection String Here" />
  </connectionStrings>
</configuration>

Customisation

Stronk provides a DSL to help guide configuration. By default, it will read from App.config or Web.config, so you usually only need to write:

var config = new StronkConfig()
    .Build<MyApplicationConfiguration>();

If you would rather populate an existing object, you can use the ApplyTo method instead of Build:

var config = new MyApplicationConfiguration();

new StronkConfig().ApplyTo(config);

You can find all default values used in the Default.cs file.

Configuration Sources

If you want to read from other sources, you can specify them using the .From DSL:

var config = new StronkConfig()
    .From.EnvironmentVariables()
    .Build<Config>();

Optionally, you can specify a prefix to environment variables, which will get stripped off when matching property names in your config (e.g. a prefix of AppOne:, will find environment variable called AppOne:Connection, and map that to a property called Connection):

var config = new StronkConfig()
    .From.EnvironmentVariables("SuperAwesomeApp:")
    .Build<Config>();

Note that if you specify sources, they will be the only ones used, so if you want to have fallbacks (e.g. read environment variables, but fallback to app.config if one is not available), you need to specify them:

var config = new StronkConfig()
    .From.EnvironmentVariables()
    .From.AppConfig()
    .Build<Config>();

Value Conversion

Stronk supports most simple types you will encounter out of the box: Enums, Uri, Guid, TimeSpan, DateTime, Nullable<>, CSV (of any type!), as well as all value types.

Converters are created by implementing IValueConverter, or you can use the LambdaValueConverter<T> if you need something simple (for example, Guid conversion is defined as new LambdaValueConverter<Guid>(Guid.Parse)).

You can either add additional value converters to what Stronk can use by default:

var config = new StronkConfig()
    .Convert.Using(new LambdaValueConverter<CustomThing>(val => CustomThing.Parse(val)))
    .Build<Config>();

Or replace all default converters with your own (not recommended!):

var config = new StronkConfig()
    .Convert.UsingOnly(new LambdaValueConverter<CustomThing>(val => CustomThing.Parse(val)))
    .Build<Config>();

Property Mapping

By default, Stronk will pick from values in your configuration sources where the key matches the property name (case insensitive). If you want to replace this behaviour, you can implement a custom IPropertyMapper:

public class PropertyNamePropertyMapper : IPropertyMapper
{
    public string ValueFor(PropertyMapperArgs args) => args.GetValue(args.Property.Name);
}
var config = new StronkConfig()
    .Map.With(new PropertyNamePropertyMapper())
    .Build<Config>();

Property Writing

By default, Stronk can write to properties with a setter (no matter its visibility), and to backing fields for properties, when the backing field is the same, but with the _ prefix (again, case insensitive). It prefers the properties with setters.

You can override this using the .Write DSL:

var config = new StronkConfig()
    .Write.To(new BackingFieldPropertyWriter())
    .Build<Config>();

If Stronk cannot find a value for a property, it will throw a SourceValueNotFoundException. If you do need an optional property, you do one of the following:

Make the type of the property Nullable:

public class Configuration
{
    public bool? IsLive { get; private set; }
}

Mark the property as optional with an attribute whose name starts with Optional:

public class Configuration
{
    [Optional]
    public string IsLive { get; private set; }
}

public class OptionalAttribute : Attribute {}

Validation

It's always a good idea to make sure your configuration is not only validly loaded, but also that the values make semantic sense. For example, if you have a Timeout property being mapped to a TimeSpan, not only should the value be formatted correctly, but there is a probably a minimum and maximum value which would make sense too.

var config = new StronkConfig()
    .Validate.Using<Configuration>(c =>
    {
        if (c.Timeout < TimeSpan.FromSeconds(60) && c.Timeout > TimeSpan.Zero)
            throw new ArgumentOutOfRangeException(nameof(c.Timeout), $"Must be greater than 0, and less than 1 minute");
    });
    .Build<Config>();

You can of course use other libraries (such as FluentValidation) to perform the actual validation, in which case your configuration might look like this:

var config = new StronkConfig()
    .Validate.Using<Configuration>(c => new ConfigValidator().Validate(c))
    .Build<Config>();

Logging

Want to know what Stronk did while populating your object? You can specify a logger to use with the .Log DSL:

var config = new StronkConfig()
    .Log.Using(message => Log.Debug(message.Template, message.Args))
    .Build<Config>();

The log messages are structured - so you can use them directly with Serilog or similar libraries. If your logging library is not structured, just call .ToString() on the message object, and you will get a flat string, with all that useful structure gone.

Questions

Why not use Microsoft.Configuration?

That didn't exist when I wrote this library. Also, support for non dotnet core is somewhat lacking (e.g. reading a web.config in XML).

Will you support dotnet core

Undecided.<br /> I could move the only dependency on ConfigurationManager to a separate package and then target core...but if you're on core, you might as well use Microsoft.Configuration.

How about Json configuration files?

I might add this as a separate package in the future (e.g. Stronk.Sources.Json or similar), but I don't want (any) dependencies on other libraries from the main Stronk library.

How about deserializing json inside a value?

Implement a custom IValueConverter.

I have other questions

Cool! Either open an issue on this repo or feel free to tweet me (@pondidum) 😃

Product Compatible and additional computed target framework versions.
.NET Framework net451 is compatible.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.5.1

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Stronk:

Package Downloads
Stronk.Source.Consul

Consul configuration source for Stronk.

Stronk.Validation.FluentValidation

FluentValidation extensions for Stronk.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
5.4.0 1,360 10/14/2018
5.3.1 834 8/26/2018
5.3.0 797 8/26/2018
5.2.0 867 8/10/2018
5.1.0 1,058 5/4/2018
5.0.0 916 4/17/2018
4.0.0 1,463 10/17/2017
3.0.0 1,158 7/2/2017
2.0.0 1,049 12/29/2016
1.0.2 1,058 12/9/2016
1.0.1 992 12/7/2016
1.0.0 967 12/5/2016