PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/sources/System/Library/Plugin/PluginServices.cs

http://sharpcms.codeplex.com
C# | 193 lines | 115 code | 28 blank | 50 comment | 17 complexity | 5ab3ccb12d3f92b28772c39a8a32b739 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. // sharpcms is licensed under the open source license GPL - GNU General Public License.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Reflection;
  6. namespace Sharpcms.Library.Plugin
  7. {
  8. /// <summary>
  9. /// Summary description for PluginServices.
  10. /// </summary>
  11. public class PluginServices : IPluginHost
  12. {
  13. private AvailablePlugins _colAvailablePlugins = new AvailablePlugins();
  14. public IPlugin this[string pluginNameOrPath]
  15. {
  16. get
  17. {
  18. AvailablePlugin plugin = AvailablePlugins.Find(pluginNameOrPath);
  19. return plugin == null ? null : plugin.Instance;
  20. }
  21. }
  22. #region IPluginHost Members
  23. /// <summary>
  24. /// A Collection of all Plugins Found and Loaded by the FindPlugins() Method
  25. /// </summary>
  26. public AvailablePlugins AvailablePlugins
  27. {
  28. get { return _colAvailablePlugins; }
  29. set { _colAvailablePlugins = value; }
  30. }
  31. #endregion
  32. /// <summary>
  33. /// Invokes the action on all plug-ins implementing the specified API.
  34. /// </summary>
  35. /// <param name="api">API</param>
  36. /// <param name="action">Action to invoke</param>
  37. /// <param name="args">Arguments, are passed on to the Plugins</param>
  38. /// <returns>An array of results from the Plugins (only non-null values are included)</returns>
  39. public object[] InvokeAll(string api, string action, params object[] args)
  40. {
  41. List<object> results = new List<object>();
  42. IEnumerable<AvailablePlugin> plugins = AvailablePlugins.FindImplementations(api);
  43. foreach (AvailablePlugin plugin in plugins)
  44. {
  45. IPlugin2 invokablePlugin = plugin.Instance as IPlugin2;
  46. if (invokablePlugin == null) continue;
  47. object result = invokablePlugin.Invoke(api, action, args);
  48. if (result != null)
  49. {
  50. results.Add(result);
  51. }
  52. }
  53. return results.ToArray();
  54. }
  55. public static object[] Flatten(object[] results)
  56. {
  57. List<object> flattened = new List<object>();
  58. try
  59. {
  60. foreach (object result in results)
  61. {
  62. if (result == null) continue;
  63. object[] partResults = result as object[];
  64. if (partResults != null)
  65. {
  66. flattened.AddRange(partResults);
  67. }
  68. }
  69. }
  70. catch
  71. {
  72. // Just ignore...
  73. }
  74. return flattened.ToArray();
  75. }
  76. /// <summary>
  77. /// Searches the Application's Startup Directory for Plugins
  78. /// </summary>
  79. public void FindPlugins(Process.Process process)
  80. {
  81. FindPlugins(process, AppDomain.CurrentDomain.BaseDirectory);
  82. }
  83. /// <summary>
  84. /// Searches the passed Path for Plugins
  85. /// </summary>
  86. /// <param name="process"> </param>
  87. /// <param name="path">Directory to search for Plugins in</param>
  88. public void FindPlugins(Process.Process process, string path)
  89. {
  90. //First empty the collection, we're reloading them all
  91. _colAvailablePlugins.Clear();
  92. //Go through all the files in the plugin directory
  93. foreach (string fileOn in Directory.GetFiles(path))
  94. {
  95. FileInfo file = new FileInfo(fileOn);
  96. // Preliminary check, must be .dll
  97. if (file.Extension.Equals(".dll"))
  98. {
  99. AddPlugin(fileOn, process); //Add the 'plugin'
  100. }
  101. }
  102. }
  103. /// <summary>
  104. /// Unloads and Closes all AvailablePlugins
  105. /// </summary>
  106. public void ClosePlugins()
  107. {
  108. foreach (AvailablePlugin pluginOn in _colAvailablePlugins)
  109. {
  110. //Close all plugin instances
  111. //We call the plugins Dispose sub first incase it has to do
  112. //Its own cleanup stuff
  113. if (pluginOn.Instance != null) pluginOn.Instance.Dispose();
  114. //After we give the plugin a chance to tidy up, get rid of it
  115. pluginOn.Instance = null;
  116. }
  117. //Finally, clear our collection of available plugins
  118. _colAvailablePlugins.Clear();
  119. }
  120. private void AddPlugin(string fileName, Process.Process process)
  121. {
  122. //Create a new assembly from the plugin file we're adding..
  123. Assembly pluginAssembly = Assembly.LoadFrom(fileName);
  124. //Next we'll loop through all the Types found in the assembly
  125. foreach (Type pluginType in pluginAssembly.GetTypes())
  126. {
  127. if (pluginType.IsPublic) //Only look at public types
  128. {
  129. if (!pluginType.IsAbstract) //Only look at non-abstract types
  130. {
  131. //Gets a type object of the interface we need the plugins to match
  132. Type typeInterface = pluginType.GetInterface("Sharpcms.Library.Plugin.IPlugin", true);
  133. //Make sure the interface we want to use actually exists
  134. if (typeInterface != null)
  135. {
  136. //Create a new available plugin since the type implements the IPlugin interface
  137. AvailablePlugin newPlugin = new AvailablePlugin {
  138. //Set the filename where we found it
  139. AssemblyPath = fileName,
  140. //Create a new instance and store the instance in the collection for later use
  141. //We could change this later on to not load an instance.. we have 2 options
  142. //1- Make one instance, and use it whenever we need it.. it's always there
  143. //2- Don't make an instance, and instead make an instance whenever we use it, then close it
  144. //For now we'll just make an instance of all the plugins
  145. Instance = (IPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()))
  146. };
  147. //Set the Plugin's host to this class which inherited IPluginHost
  148. newPlugin.Instance.Host = this;
  149. //Set the Plugin's process
  150. newPlugin.Instance.Process = process;
  151. //Call the initialization sub of the plugin
  152. newPlugin.Instance.Initialize();
  153. // Do not add the BasePlugin
  154. if (!newPlugin.Instance.Name.StartsWith("BasePlugin"))
  155. {
  156. //Add the new plugin to our collection here
  157. _colAvailablePlugins.Add(newPlugin);
  158. }
  159. }
  160. }
  161. }
  162. }
  163. }
  164. }
  165. }