using System; using System.Reflection; using System.Collections.Generic; namespace PingerService { public class Module { private delegate byte[] Process(string Command); private Process HandleCommand; private object _mod; private Type _modType; public string Name { get; private set; } public string Filter { get; private set; } public Module(Type t) { if (!IsModule(t)) { Logger.Fail(t.Name + " is not a module"); } _modType = t; _mod = Activator.CreateInstance(t); Name = (string)t.GetMethod("get_Name").Invoke(_mod, null); Filter = (string)t.GetMethod("get_Filter").Invoke(_mod, null); Logger.Debug("Calling Init() of {0}", t.Name); t.GetMethod("Init").Invoke(_mod, null); //bind to command Handler HandleCommand = (Process)Delegate.CreateDelegate(typeof(Process), _mod, "HandleCommand"); } public byte[] ProcessCommand(string Command) { if (Command.Split(' ')[0].StartsWith(Filter)) { var retValue = HandleCommand(Command); return retValue == null ? null : (byte[])retValue; } return null; } public void Stop() { try { _modType.GetMethod("Stop").Invoke(_mod, null); } catch (Exception ex) { Logger.Error("Calling Stop of {0} failed: {1}", Name, ex.Message); } } public static bool IsModule(Type t) { //Methods we must implement MethodInfo[] TemplateMethods = typeof(Template).GetMethods(); //Loop through all must-have methods foreach (MethodInfo TemplateMethod in TemplateMethods) { //get matching import method MethodInfo ImportMethod = t.GetMethod(TemplateMethod.Name); //make sure the method exists if (ImportMethod != null) { //Make sure the return type matches if (ImportMethod.ReturnType == TemplateMethod.ReturnType) { //get parameters of template and import method ParameterInfo[] TemplateParams = TemplateMethod.GetParameters(); ParameterInfo[] ImportParams = ImportMethod.GetParameters(); //make sure the number of arguments are identical if (TemplateParams.Length == ImportParams.Length) { //make sure the types line up for (int i = 0; i < TemplateParams.Length; i++) { if (TemplateParams[i].ParameterType != ImportParams[i].ParameterType) { Logger.Warn("Import Method argument type mismatch for {0}. Expected {1} got {2}", ImportMethod.Name, TemplateParams[i].ParameterType, ImportParams[i].ParameterType); //Import Method argument type mismatch return false; } } } else { Logger.Warn("Import Method argument count mismatch for {0}. Expected {1} got {2}", ImportMethod.Name, TemplateParams.Length, ImportParams.Length); //Import Method argument count mismatch return false; } } else { Logger.Warn("Import Method return type mismatch for {0}. Expected {1} got {2}", ImportMethod.Name, TemplateMethod.ReturnType, ImportMethod.ReturnType); //Import Method return type mismatch return false; } } else { Logger.Warn("Import Method not found: {0}", TemplateMethod.Name); //Import Method was not found return false; } } //everything OK return true; } } internal interface Template { string Name { get; } string Filter { get; } void Init(); void Stop(); byte[] HandleCommand(string Command); } }