/// <summary> /// Loads an assembly and determines if it contains an object that implements the module interface. /// </summary> /// <param name="path">Full path and name of the assembly to load</param> /// <returns>Information about the object that implements the module interface if one could be found in the assembly.</returns> public GameModuleInfo LoadAssembly(string path) { GameModuleInfo result = null; Assembly asm = Assembly.LoadFrom(path); Type[] types = asm.GetExportedTypes(); foreach (Type t in types) { if ((t.GetInterface("IGameModule") != null) && !t.IsAbstract) { object tempObj = Activator.CreateInstance(t); result = new GameModuleInfo(); result.Name = t.GetProperty("Name").GetValue(tempObj, null).ToString(); result.IdentityCode = t.GetProperty("IdentityCode").GetValue(tempObj, null).ToString(); result.Priority = (int)t.GetProperty("Priority").GetValue(tempObj, null); result.IsRequired = (t.GetProperty("IsRequired").GetValue(tempObj, null) as bool?) == true ? true : false; result.ObjectClassType = t.FullName; } } return(result); }
/// <summary> /// Loads in the module class libraries. /// </summary> /// <returns>A flag indicating if the modules were successfully loaded. If false the application should be shut down.</returns> private bool LoadModules() { List <GameModuleInfo> availableModules = new List <GameModuleInfo>(); HashSet <string> dependentModules = new HashSet <string>(); int modulesToLoad = 0; // build a temporary domain to check the modules to load. string pathToDll = Assembly.GetExecutingAssembly().CodeBase; AppDomainSetup domainSetup = new AppDomainSetup { PrivateBinPath = pathToDll }; AppDomain domain = AppDomain.CreateDomain("TempDomain", null, domainSetup); InstanceProxy proxy = domain.CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(InstanceProxy)).FullName, typeof(InstanceProxy).ToString()) as InstanceProxy; if (proxy != null) { DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); foreach (FileInfo fi in di.GetFiles("*.dll")) { GameModuleInfo m = proxy.LoadAssembly(fi.Name); if (m != null) { if ((AppObjects.Constants as AppConstants).ModulesToBeLoaded.Contains(m.Name.Replace(" ", string.Empty)) || m.IsRequired) { m.Load = true; modulesToLoad++; } #if DEBUG // In debug always load all modules. m.Load = true; #endif m.CodeBase = fi.Name; availableModules.Add(m); } } } // Verify that all dependent modules are loaded. if (modulesToLoad != 0) { #if DEBUG /* todo: * if ((AppObjects.Overrides != null) && AppObjects.Overrides.SelectModules) * { * using (System.Windows.Forms.FrmLoadModules frm = new System.Windows.Forms.FrmLoadModules(availableModules, dependentModules)) * { * if (frm.ShowDialog() == DialogResult.OK) * { * availableModules = frm.GetModulesToLoad(); * } * } * }*/ #endif } // Finally load the needed modules into the current domain. foreach (GameModuleInfo mi in availableModules.OrderBy(m => m.Priority)) { if (!string.IsNullOrEmpty(mi.CodeBase) && mi.Load) { // Add the module to the dispose wrapper so they get disposed with the form. // todo: this.disposeWrapper1.ItemsToDispose.Add(m); Assembly a = Assembly.LoadFrom(mi.CodeBase); IGameModule m = Activator.CreateInstance(a.GetType(mi.ObjectClassType)) as IGameModule; (AppObjects.Constants as AppConstants).LoadedModules.Add(m); } } AppDomain.Unload(domain); return((AppObjects.Constants as AppConstants).LoadedModules.Count > 0); }