Created
August 17, 2012 16:03
-
-
Save drch-/3380180 to your computer and use it in GitHub Desktop.
typed appsesttings config reader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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