/// <summary> /// Finds the MagicSymbols inside an assembly, and returns an instance of each. /// </summary> public IEnumerable <MagicSymbol> FindMagic(AssemblyInfo assm) { var result = new MagicSymbol[0]; if (cache.TryGetValue(assm, out result)) { return(result); } this.logger.LogInformation($"Looking for MagicSymbols in {assm.Assembly.FullName}"); // If types from an assembly cannot be loaded, log a warning and continue. var allMagic = new List <MagicSymbol>(); try { var magicTypes = assm.Assembly .GetTypes() .Where(t => { if (!t.IsClass && t.IsAbstract) { return(false); } var matched = t.IsSubclassOf(typeof(MagicSymbol)); this.logger.LogDebug("Class {Class} subclass of MagicSymbol? {Matched}", t.FullName, matched); return(matched); }); foreach (var t in magicTypes) { try { var m = ActivatorUtilities.CreateInstance(services, t) as MagicSymbol; allMagic.Add(m); this.logger.LogInformation($"Found MagicSymbols {m.Name} ({t.FullName})"); } catch (Exception e) { this.logger.LogWarning($"Unable to create instance of MagicSymbol {t.FullName}. Magic will not be enabled.\nMessage:{e.Message}"); } } } catch (Exception ex) { this.logger.LogWarning( ex, "Encountered exception loading types from {AssemblyName}.", assm.Assembly.FullName ); } result = allMagic.ToArray(); cache[assm] = result; return(result); }
/// <inheritdoc /> public IEnumerable <MagicSymbol> FindMagic(AssemblyInfo assm) { var result = new MagicSymbol[0]; lock (cache) { if (cache.TryGetValue(assm, out result)) { return(result); } this.logger.LogInformation($"Looking for MagicSymbols in {assm.Assembly.FullName}"); // If types from an assembly cannot be loaded, log a warning and continue. var allMagic = new List <MagicSymbol>(); try { var magicTypes = assm.Assembly .GetTypes() .Where(t => { if (!t.IsClass && t.IsAbstract) { return(false); } var matched = t.IsSubclassOf(typeof(MagicSymbol)); // This logging statement is expensive, so we only run it when we need to for debugging. #if DEBUG this.logger.LogDebug("Class {Class} subclass of MagicSymbol? {Matched}", t.FullName, matched); #endif return(matched); }); foreach (var t in magicTypes) { try { var symbol = ActivatorUtilities.CreateInstance(services, t); if (symbol is MagicSymbol magic) { allMagic.Add(magic); this.logger.LogInformation($"Found MagicSymbols {magic.Name} ({t.FullName})"); } else if (symbol is {}) { throw new Exception($"Unable to create magic symbol of type {t}; service activator returned an object of type {symbol.GetType()}, which is not a subtype of MagicSymbol."); } else if (symbol == null) { throw new Exception($"Unable to create magic symbol of type {t}; service activator returned null."); } }
/// <summary> /// Finds the MagicSymbols inside an assembly, and returns an instance of each. /// </summary> public IEnumerable <MagicSymbol> FindMagic(AssemblyInfo assm) { var result = new MagicSymbol[0]; if (cache.TryGetValue(assm, out result)) { return(result); } this.logger.LogInformation($"Looking for MagicSymbols in {assm.Assembly.FullName}"); var magicTypes = assm.Assembly .GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(MagicSymbol))); var allMagic = new List <MagicSymbol>(); foreach (var t in magicTypes) { try { var m = ActivatorUtilities.CreateInstance(services, t) as MagicSymbol; allMagic.Add(m); this.logger.LogInformation($"Found MagicSymbols {m.Name} ({t.FullName})"); } catch (Exception e) { this.logger.LogWarning($"Unable to create instance of MagicSymbol {t.FullName}. Magic will not be enabled.\nMessage:{e.Message}"); } } result = allMagic.ToArray(); cache[assm] = result; return(result); }
public static void Test(this MagicSymbol magic, string input, ExecuteStatus expected = ExecuteStatus.Ok) { var result = magic.Execute(input, new MockChannel()).GetAwaiter().GetResult(); Assert.IsTrue(result.Status == expected); }