Sunday, October 25, 2015

Override Configuration via Command Line

In my previous blog posts I have talked about creating complex config objects from your app.config file, as well as how to have cascading configuration settings from multiple files. Now I want to build on that concept by taking in configuration from command line in a generic fashion that will override your other cascading settings.

Configuration Object

public class TestConfig
{
    public string Hello { get; set; }
    public string Goodnight { get; set; }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="TestConfig.Hello" value="World" />
    <add key="TestConfig.Goodnight" value="Moon" />
  </appSettings>
</configuration>

ConfigurationHelpers.FromCommandLine

Please note that this is a very simple implementation of how to parse the command line arguments and will not be resilient to all inputs.

public static class ConfigurationHelpers
{
    public static NameValueCollection FromCommandLine(
        string args, 
        string argsDelimeter = " ",
        string prefix = "/s:",
        string valueDelimeter = "=")
    {
        var result = new NameValueCollection();
 
        var splitArgs = args.Split(
            new[] {argsDelimeter},
            StringSplitOptions.RemoveEmptyEntries);
 
        foreach (var arg in splitArgs)
        {
            if (!arg.StartsWith(prefix))
            {
                continue;
            }
 
            var i = arg.IndexOf('=');
            if (i == -1)
            {
                continue;
            }
 
            var key = arg.Substring(prefix.Length, i - prefix.Length);
            var value = arg.Substring(i + 1);
            result.Add(key, value);
        }
 
        return result;
    }
}

Unit Tests

public class ConfigurationHelpersTests
{
    [Theory]
    [InlineData("/s:TestConfig.Hello=Hello", 1, "Hello")]
    [InlineData("/s:TestConfig.Goodnight=Dawg", 1, "World")]
    [InlineData("/s:TestConfig.Hello=There /s:TestConfig.Goodnight=Dawg", 2, "There")]
    public void FromCommandLine(string args, int count, string helloValue)
    {
        var map = ConfigurationHelpers.FromCommandLine(args);
 
        Assert.Equal(count, map.Count);
 
        var combined = map.Combine(ConfigurationManager.AppSettings);
        var config = combined.CreateObject<TestConfig>(string.Empty);
 
        Assert.Equal(helloValue, config.Hello);
    }
}

Enjoy,
Tom

No comments:

Post a Comment

Real Time Web Analytics