Skip to content

Instantly share code, notes, and snippets.

@NearlyUnique
Last active March 1, 2016 12:12
Show Gist options
  • Save NearlyUnique/c46062f5219b5d707af6 to your computer and use it in GitHub Desktop.
Save NearlyUnique/c46062f5219b5d707af6 to your computer and use it in GitHub Desktop.
A wrapper around various configuration sources
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
namespace namespace NearlyUnique.Config
{
/// <summary>
/// A wrapper for multiple configuration sources
/// </summary>
public class Configurator
{
private readonly List<Func<string, string>> _sources = new List<Func<string, string>>();
private static readonly Dictionary<Type, Func<string, object>> Convertor = new Dictionary<Type, Func<string, object>>
{
{typeof (string), x => x},
{typeof (int), x => {int val;return int.TryParse(x, out val) ? (int?)val : null;}},
{typeof (bool), x => {bool val;return bool.TryParse(x, out val) ? (bool?)val : null;}}
};
/// <summary>
/// basic c'tor, if non sources supplied defaults: pre-register Commandline, AppConfig then EnvironmentVariable in that order
/// </summary>
public Configurator(params Func<string,string>[] sources)
{
if (sources == null || sources.Length == 0)
{
AddSource(Source.Commandline);
AddSource(Source.AppConfig);
AddSource(Source.EnvironmentVariable);
}
else
{
foreach (var source in sources)
{
AddSource(source);
}
}
}
/// <summary>
/// Remove all sources, typically the default ones when testing or using a completley custom source order
/// </summary>
public void ClearSources()
{
_sources.Clear();
}
/// <summary>
/// Add additional source
/// </summary>
/// <param name="source"></param>
public void AddSource(Func<string, string> source)
{
_sources.Add(source);
}
/// <summary>
/// return the first registered Source that has a non-null value
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string Get(string key)
{
return _sources
.Select(src => src(key))
.FirstOrDefault(val => val != null);
}
public T? GetValue<T>(string key) where T : struct
{
return (T?)Convertor[typeof(T)](Get(key));
}
/// <summary>
/// Some common helper sources
/// </summary>
public static class Source
{
/// <summary>
/// From app.config or web.config &lt;add value=&quot;THE_KEY_NAME&quot; value=&quot;SOME_VALUE&quot; /&gt;
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string AppConfig(string key)
{
return ConfigurationManager.AppSettings[key];
}
/// <summary>
/// Standard environment variable, windows `SET THE_KEY_NAME=SOME_VALUE`
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string EnvironmentVariable(string key)
{
return Environment.GetEnvironmentVariable(key);
}
/// <summary>
/// command line argument in the form `-key:THE_KEY_NAME=SOME_VALUE`, no spaces in key or value
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string Commandline(string key)
{
var m = Regex.Match(Environment.CommandLine, @"-key:(.*?)=([^\s]*)");
if (m.Success && key == m.Groups[1].Value)
{
return m.Groups[2].Value;
}
return null;
}
/// <summary>
/// From a standard Dictionary&lt;string, string&gt; the key used as is
/// </summary>
/// <param name="dictionary"></param>
/// <returns></returns>
public static Func<string, string> FromDictionary(Dictionary<string, string> dictionary)
{
return x =>
{
string value;
return dictionary.TryGetValue(x, out value) ? value : null;
};
}
}
}
}
@NearlyUnique
Copy link
Author

Added ClearSources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment