This is an old revision of the document!
I need to just derive stuff from something, and all the derived types I'll register somewhere, or initialize, or something like that - but I don't want to also have to have an ever-growing list of tasks for each
var subtypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(domainAssembly => domainAssembly.GetTypes()) .Where(type => type.IsSubclassOf(typeof(MyAbstractClass)) && !type.IsAbstract) .ToList(); foreach (var subtype in subtypes) { var instance = (MyAbstractClass) Activator.CreateInstance(subtype); }
so you make an abstract class `MyAbstractClass` and derive from it.
static List<Task<Report>> CollectReporters(Configuration conf) { var toReturn = new List<Task<Report>>(); var reporterTypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(domainAssembly => domainAssembly.GetTypes()) .Where(type => type.IsSubclassOf(typeof(newsletter.Reporters.Reporter)) && !type.IsAbstract) .ToList(); var skipPortionInName = "newsletter.Reporters.".Length; foreach(var discoveredConfType in conf.Reporters.Select(r => r.ReporterClass)) { Console.WriteLine($"{discoveredConfType} configuration type discovered"); } foreach (var reporterType in reporterTypes) { Console.WriteLine($"{reporterType.ToString().Substring(skipPortionInName).ToLower()} reporter class discovered"); Func<Configuration.Reporter, bool> predicate = r => r.ReporterClass == reporterType.ToString().Substring(skipPortionInName).ToLower(); if (!conf.Reporters.Any(predicate)) { Console.WriteLine($"no configurations for it"); } else { var configurationsFor = conf.Reporters.Where(predicate); Console.WriteLine($"{configurationsFor.Count()} configurations for it"); foreach (var confFor in configurationsFor) { var instance = (newsletter.Reporters.Reporter) Activator.CreateInstance(reporterType); toReturn.Add(instance.Report(confFor)); } } } return toReturn; }
observe - I write a text string in a config file to describ ea type, and now I can pick what object to instantiate :)))