using System.Collections;
using System.Collections.Generic;
public static void Main()
var configurationLoader = new GaryExample.Service.ConfigurationLoader();
var config = configurationLoader.LoadApplicationConfiguration();
Console.WriteLine("RUNNING A RULES:");
foreach(var aRule in config.ARules)
Console.WriteLine("RUNNING B RULES:");
foreach(var bRule in config.BRules)
namespace GaryExample.Service
public class ConfigurationLoader
public GaryExample.Domain.Configuration.ApplicationConfiguration LoadApplicationConfiguration()
var persistedConfig = GaryExample.DataAccess.Configuration.StaticConfigurationProvider.GetConfig();
var domainConfig = new GaryExample.Domain.Configuration.ApplicationConfiguration();
foreach(var domainProperty in typeof(GaryExample.Domain.Configuration.ApplicationConfiguration).GetProperties())
var enumerableType = domainProperty.PropertyType.GetInterfaces().FirstOrDefault(t=>t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
if (enumerableType != null)
var genericType = enumerableType.GetGenericArguments().First();
var matchingPersistedRules = persistedConfig.Where(r=>r.Interface == genericType.FullName).ToList();
if (matchingPersistedRules.Any())
var matchingDomainRules = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(genericType));
foreach(var matchingPersistedRule in matchingPersistedRules)
var concreteType = Type.GetType(matchingPersistedRule.Implementation);
object instance = Activator.CreateInstance(concreteType);
foreach(var ruleProperty in concreteType.GetProperties())
var matchingProperty = matchingPersistedRule.Properties.FirstOrDefault(p=>p.Name == ruleProperty.Name);
if (matchingProperty != null)
var propertyValue = Convert.ChangeType(matchingProperty.Value, Type.GetType(matchingProperty.Type));
ruleProperty.SetValue(instance,propertyValue);
matchingDomainRules.Add(instance);
domainProperty.SetValue(domainConfig, matchingDomainRules);
namespace GaryExample.Domain.Configuration
public class ApplicationConfiguration
public List<GaryExample.Domain.Rule.IRuleTypeA> ARules {get;set;}
public List<GaryExample.Domain.Rule.IRuleTypeB> BRules {get;set;}
namespace GaryExample.Domain.Rule
public interface IRuleTypeA
public interface IRuleTypeB
public class RuleAOne : IRuleTypeA
public void DoARuleThings()
Console.WriteLine("Rule A One doing it's thing");
public class RuleATwo : IRuleTypeA
public string SpecialValue {get;set;}
public void DoARuleThings()
Console.WriteLine(string.Format("Rule A Two doing it's thing with special value: {0}", SpecialValue));
public class RuleBOne : IRuleTypeB
public string SuperSpecialValue {get;set;}
public void DoBRuleThings()
if (string.IsNullOrEmpty(SuperSpecialValue))
Console.WriteLine("Rule B One doing it's thing");
Console.WriteLine(string.Format("Rule B On doing it's thing with SUPER special value: {0}", SuperSpecialValue));
public class RuleBTwo : IRuleTypeB
public bool WriteCoolStuff {get;set;}
public void DoBRuleThings()
Console.WriteLine("Rule B Two writing cool stuff");
Console.WriteLine("Rule B Two writing BORING stuff");
namespace GaryExample.DataAccess.Configuration
public static class StaticConfigurationProvider
public static List<RuleConfig> GetConfig()
return new List<RuleConfig>
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeA", Implementation = "GaryExample.Domain.Rule.RuleAOne", },
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeA", Implementation = "GaryExample.Domain.Rule.RuleATwo", Properties = new List<RulePropertyConfig>{new RulePropertyConfig { Name = "SpecialValue", Type = "System.String", Value = "Configured Special Value 1", }}},
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeA", Implementation = "GaryExample.Domain.Rule.RuleATwo", Properties = new List<RulePropertyConfig>{new RulePropertyConfig { Name = "SpecialValue", Type = "System.String", Value = "Configured Special Value 2", }}},
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeB", Implementation = "GaryExample.Domain.Rule.RuleBOne", },
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeB", Implementation = "GaryExample.Domain.Rule.RuleBOne", Properties = new List<RulePropertyConfig>{new RulePropertyConfig { Name = "SuperSpecialValue", Type = "System.String", Value = "Configured SUPER Special Value 1", }}},
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeB", Implementation = "GaryExample.Domain.Rule.RuleBTwo", Properties = new List<RulePropertyConfig>{new RulePropertyConfig { Name = "WriteCoolStuff", Type = "System.Boolean", Value = "True", }}},
new RuleConfig { Interface = "GaryExample.Domain.Rule.IRuleTypeB", Implementation = "GaryExample.Domain.Rule.RuleBTwo", Properties = new List<RulePropertyConfig>{new RulePropertyConfig { Name = "WriteCoolStuff", Type = "System.Boolean", Value = "False", }}},
public string Interface {get;set;}
public string Implementation {get;set;}
public List<RulePropertyConfig> Properties {get;set;}
Properties = new List<RulePropertyConfig>();
public class RulePropertyConfig
public string Name {get;set;}
public string Type {get;set;}
public string Value {get;set;}