/// <summary> /// Loads the possible plugin assemblies in a separate AppDomain /// in order to allow unloading of unneeded assemblies. /// </summary> /// <param name="alreadyLoadedPlugIns">List of Plugins</param> public void LoadPlugIns(PlugInDataList alreadyLoadedPlugIns) { this.plugIns.Clear(); if (this.SearchDirectory == null || !Directory.Exists(this.SearchDirectory)) { throw new DirectoryNotFoundException("Could not find plugin directory"); } string baseDir = AppDomain.CurrentDomain.BaseDirectory; // Create evidence for new appdomain. Evidence adevidence = AppDomain.CurrentDomain.Evidence; // Create a setup object for the new application domain. var setup = new AppDomainSetup { PrivateBinPath = baseDir + ";" + this.SearchDirectory }; // Append the relative path // The class actually created a new instance of the same class // only in a different AppDomain. It then passes it all the needed // parameters such as search path and file extensions. AppDomain domain = AppDomain.CreateDomain("DynamicPlugInLoader", adevidence, setup); string assemblyName = baseDir + "MsiPlugInSystem.dll"; var finder = (DynamicFindPlugInProvider)domain.CreateInstanceFromAndUnwrap(assemblyName, typeof(DynamicFindPlugInProvider).ToString()); finder.FileExtensionFilter = this.FileExtensionFilter; finder.SearchDirectory = this.SearchDirectory; TypeList foundPlugInTypes = finder.SearchPath(this.SearchDirectory); if (foundPlugInTypes.Count != finder.baseObjectTypesList.Count) { throw new InvalidOperationException("Count of PlugIns and BaseObjectLists doesn't match!"); } AppDomain.Unload(domain); foreach (Type t in foundPlugInTypes) { if (t != null) { var assemblyFullName = t.Assembly.FullName; bool alreadyLoaded = false; foreach (PlugInData loadedPlugInData in alreadyLoadedPlugIns) { if (loadedPlugInData.AssemblyFullName == assemblyFullName) { alreadyLoaded = true; break; } } if (!alreadyLoaded) { object plugInInstance = Activator.CreateInstance(t); var plugIn = plugInInstance as IPlugIn; if (plugIn != null) { var plugInData = new PlugInData(plugIn); this.plugIns.Add(plugInData); } } } } }
/// <summary> /// Loads the PlugIns. /// </summary> /// <param name="alreadyLoadedPlugIns"> List of Plugins </param> public void LoadPlugIns(PlugInDataList alreadyLoadedPlugIns) { this.plugIns.Clear(); var textReader = new XmlTextReader(this.FileName); while (textReader.Read()) { if (textReader.Name == "add") { string type = textReader.GetAttribute("type"); IPlugIn plugIn = null; if (type != null) { Type plugInType = Type.GetType(type); if (plugInType != null) { object plugInInstance = Activator.CreateInstance(plugInType); plugIn = plugInInstance as IPlugIn; } } if (plugIn != null) { PlugInData plugInData = new PlugInData(plugIn); bool alreadyLoaded = false; foreach (PlugInData loadedPlugInData in this.LoadedPlugIns) { if (loadedPlugInData.AssemblyFullName == plugInData.AssemblyFullName) { alreadyLoaded = true; break; } } if (!alreadyLoaded) { this.LoadedPlugIns.Add(plugInData); } } } } // create a plugIn list to collect invalid PlugIns var invalidPlugIns = new PlugInDataList(); // try and get the baseobjects published by the PlugIn foreach (PlugInData plugInData in this.plugIns) { IPlugIn plugIn = plugInData.PlugIn; Type plugInType = plugIn.GetType(); // JP 22/12/2011 - This does not do anything System.Reflection.Assembly plugInAssembly = plugInType.Assembly; } // Remove all invalid PlugIns from the PlugIns list foreach (PlugInData plugInData in invalidPlugIns) { this.plugIns.Remove(plugInData); } }