/// <summary> /// Iterate through all the child nodes /// of the XMLNode that was passed in and create instances /// of the specified Types by reading the attribute values of the nodes /// we use a try/Catch here because some of the nodes /// might contain an invalid reference to a plugin type. /// </summary> /// <param name="parent">Parent Object</param> /// <param name="configContext">Context configuration</param> /// <param name="section">The XML section we will iterate against</param> /// <returns>List of Plugins</returns> public object Create(object parent, object configContext, XmlNode section) { var plugins = new PlugInDataList(); foreach (XmlNode node in section.ChildNodes) { // Use the Activator class's 'CreateInstance' method // to try and create an instance of the plugin by // passing in the type name specified in the attribute value if (node.Attributes != null && node.Attributes["type"] != null) { string typename = node.Attributes["type"].Value; if (typename != null) { Type type = Type.GetType(typename); if (type != null) { object plugObject = Activator.CreateInstance(type); // Cast this to an IPlugIn interface and add to the collection var plugin = plugObject as IPlugIn; if (plugin != null) { plugins.Add(new PlugInData(plugin)); } } } } } return(plugins); }
/// <summary> /// Loads the plugins. /// </summary> /// <param name="alreadyLoadedPlugIns"> The already Loaded Plug Ins. </param> public void LoadPlugIns(PlugInDataList alreadyLoadedPlugIns) { if (this.plugIns == null) { try { this.plugIns = ConfigurationManager.GetSection("plugins") as PlugInDataList; } finally { if (this.plugIns == null) { this.plugIns = new PlugInDataList(); } } } }
/// <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); } }