using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reflection; namespace Kerobot { static class ModuleLoader { private const string LogName = nameof(ModuleLoader); /// /// Given the instance configuration, loads all appropriate types from file specified in it. /// internal static ReadOnlyCollection Load(InstanceConfig conf, Kerobot k) { var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar; var modules = new List(); foreach (var file in conf.EnabledAssemblies) { Assembly a = null; try { a = Assembly.LoadFile(path + file); } catch (Exception ex) { Console.WriteLine("An error occurred when attempting to load a module assembly."); Console.WriteLine($"File: {file}"); Console.WriteLine(ex.ToString()); Environment.Exit(2); } IEnumerable amods = null; try { amods = LoadModulesFromAssembly(a, k); } catch (Exception ex) { Console.WriteLine("An error occurred when attempting to create a module instance."); Console.WriteLine(ex.ToString()); Environment.Exit(2); } modules.AddRange(amods); } return modules.AsReadOnly(); } static IEnumerable LoadModulesFromAssembly(Assembly asm, Kerobot k) { var eligibleTypes = from type in asm.GetTypes() where !type.IsAssignableFrom(typeof(ModuleBase)) where type.GetCustomAttribute() != null select type; k.InstanceLogAsync(false, LogName, $"Scanning {asm.GetName().Name}"); var newmods = new List(); foreach (var t in eligibleTypes) { var mod = Activator.CreateInstance(t, k); k.InstanceLogAsync(false, LogName, $"---> Loading module {t.FullName}"); newmods.Add((ModuleBase)mod); } return newmods; } } }