Skip to content

Instantly share code, notes, and snippets.

@drch-
Created August 17, 2012 16:03
Show Gist options
  • Save drch-/3380180 to your computer and use it in GitHub Desktop.
Save drch-/3380180 to your computer and use it in GitHub Desktop.
typed appsesttings config reader
public class AppSettingsLoader
{
public static T Load<T>() where T : new()
{
var props = typeof (T).GetProperties();
var result = new T();
foreach (var prop in props)
{
var name = GetSettingName(prop);
var setting = ConfigurationManager.AppSettings[name];
if (setting == null && IsRequired(prop))
{
throw new ArgumentNullException("Required app setting " + name + " not found");
}
object newValue = null;
var converterAttribute =
prop.GetCustomAttributes(true).FirstOrDefault(x => x is ConverterAttribute) as ConverterAttribute;
if (converterAttribute != null)
{
dynamic converter = Activator.CreateInstance(converterAttribute.Converter);
newValue = converter.Convert(setting);
}
else if (prop.PropertyType == typeof (string))
{
newValue = setting;
}
else if (prop.PropertyType.IsValueType)
{
TypeConverter tc = TypeDescriptor.GetConverter(prop.PropertyType);
newValue = tc.ConvertFromString(setting);
}
prop.SetValue(result, newValue, null);
}
return result;
}
private static string GetSettingName(PropertyInfo prop)
{
var setting =
prop.GetCustomAttributes(true).FirstOrDefault(x => x is SettingNameAttribute) as SettingNameAttribute;
return
setting != null ? setting.SettingName : prop.Name;
}
private static bool IsRequired(PropertyInfo pi)
{
return pi.GetCustomAttributes(true).Any(x => x is RequiredAttribute);
}
}
public interface IConvert<T>
{
T Convert(string source);
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ConverterAttribute : Attribute
{
public Type Converter { get; private set; }
public ConverterAttribute(Type converter)
{
if (!converter.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IConvert<>)))
{
throw new Exception("Type must be IConvert<TFrom,TTo>. Found: " + Converter.Name);
}
Converter = converter;
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class SettingNameAttribute : Attribute
{
public string SettingName { get; private set; }
public SettingNameAttribute(string name)
{
SettingName = name;
}
}
public class MyConfigOptions
{
[Required]
public string SomeRequiredProperty { get; set; }
public int SomeIntProperty { get; set; }
[SettingName("DifferentThanProperty")]
public double SomePropertyWithADifferentName { get; set; }
[Converter(typeof(UnixTimestampDateConverter))] // IConvert<DateTime>
[SettingName("UnixTimestamp")]
public DateTime TimeStamp { get; set; }
}
public void Foo() {
var config = AppSettingsLoader.Load<MyConfigOptions>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment