1using System;2using System.IO;3using System.Reflection;4using PluginInterface;56namespace IntelliDispatch7{8/// <summary>9/// Summary description for PluginServices.10/// </summary>11public class PluginServices : IPluginHost //<--- Notice how it inherits IPluginHost interface!12{13/// <summary>14/// Constructor of the Class15/// </summary>16public PluginServices()17{18}1920private Types.AvailablePlugins colAvailablePlugins = new Types.AvailablePlugins();2122/// <summary>23/// A Collection of all Plugins Found and Loaded by the FindPlugins() Method24/// </summary>25public Types.AvailablePlugins AvailablePlugins26{27get {return colAvailablePlugins;}28set {colAvailablePlugins = value;}29}3031/// <summary>32/// Searches the Application's Startup Directory for Plugins33/// </summary>34public void FindPlugins()35{36FindPlugins(AppDomain.CurrentDomain.BaseDirectory);37}38/// <summary>39/// Searches the passed Path for Plugins40/// </summary>41/// <param name="Path">Directory to search for Plugins in</param>42public void FindPlugins(string Path)43{44//First empty the collection, we're reloading them all45colAvailablePlugins.Clear();4647//Go through all the files in the plugin directory48foreach (string fileOn in Directory.GetFiles(Path))49{50FileInfo file = new FileInfo(fileOn);5152//Preliminary check, must be .dll53if (file.Extension.Equals(".dll"))54{55//Add the 'plugin'56this.AddPlugin(fileOn);57}58}59}6061/// <summary>62/// Unloads and Closes all AvailablePlugins63/// </summary>64public void ClosePlugins()65{66foreach (Types.AvailablePlugin pluginOn in colAvailablePlugins)67{68//Close all plugin instances69//We call the plugins Dispose sub first incase it has to do70//Its own cleanup stuff71pluginOn.Instance.Dispose();7273//After we give the plugin a chance to tidy up, get rid of it74pluginOn.Instance = null;75}7677//Finally, clear our collection of available plugins78colAvailablePlugins.Clear();79}8081private void AddPlugin(string FileName)82{83//Create a new assembly from the plugin file we're adding..84Assembly pluginAssembly = Assembly.LoadFrom(FileName);8586//Next we'll loop through all the Types found in the assembly87foreach (Type pluginType in pluginAssembly.GetTypes())88{89if (pluginType.IsPublic) //Only look at public types90{91if (!pluginType.IsAbstract) //Only look at non-abstract types92{93//Gets a type object of the interface we need the plugins to match94Type typeInterface = pluginType.GetInterface("PluginInterface.IPlugin", true);9596//Make sure the interface we want to use actually exists97if (typeInterface != null)98{99//Create a new available plugin since the type implements the IPlugin interface100Types.AvailablePlugin newPlugin = new Types.AvailablePlugin();101102//Set the filename where we found it103newPlugin.AssemblyPath = FileName;104105//Create a new instance and store the instance in the collection for later use106//We could change this later on to not load an instance.. we have 2 options107//1- Make one instance, and use it whenever we need it.. it's always there108//2- Don't make an instance, and instead make an instance whenever we use it, then close it109//For now we'll just make an instance of all the plugins110newPlugin.Instance = (IPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));111112//Set the Plugin's host to this class which inherited IPluginHost113newPlugin.Instance.Host = this;114115//Call the initialization sub of the plugin116newPlugin.Instance.Initialize();117118//Add the new plugin to our collection here119this.colAvailablePlugins.Add(newPlugin);120121//cleanup a bit122newPlugin = null;123}124125typeInterface = null; //Mr. Clean126}127}128}129130pluginAssembly = null; //more cleanup131}132133/// <summary>134/// Displays a feedback dialog from the plugin135/// </summary>136/// <param name="Feedback">String message for feedback</param>137/// <param name="Plugin">The plugin that called the feedback</param>138public void Feedback(string Feedback, IPlugin Plugin)139{140//This sub makes a new feedback form and fills it out141//With the appropriate information142//This method can be called from the actual plugin with its Host Property143144System.Windows.Forms.Form newForm = null;145frmFeedback newFeedbackForm = new frmFeedback();146147//Here we set the frmFeedback's properties that i made custom148newFeedbackForm.PluginAuthor = "By: " + Plugin.Author;149newFeedbackForm.PluginDesc = Plugin.Description;150newFeedbackForm.PluginName = Plugin.Name;151newFeedbackForm.PluginVersion = Plugin.Version;152newFeedbackForm.Feedback = Feedback;153154//We also made a Form object to hold the frmFeedback instance155//If we were to declare if not as frmFeedback object at first,156//We wouldn't have access to the properties we need on it157newForm = newFeedbackForm;158newForm.ShowDialog();159160newFeedbackForm = null;161newForm = null;162163}164}165namespace Types166{167/// <summary>168/// Collection for AvailablePlugin Type169/// </summary>170public class AvailablePlugins : System.Collections.CollectionBase171{172//A Simple Home-brew class to hold some info about our Available Plugins173174/// <summary>175/// Add a Plugin to the collection of Available plugins176/// </summary>177/// <param name="pluginToAdd">The Plugin to Add</param>178public void Add(Types.AvailablePlugin pluginToAdd)179{180this.List.Add(pluginToAdd);181}182183/// <summary>184/// Remove a Plugin to the collection of Available plugins185/// </summary>186/// <param name="pluginToRemove">The Plugin to Remove</param>187public void Remove(Types.AvailablePlugin pluginToRemove)188{189this.List.Remove(pluginToRemove);190}191192/// <summary>193/// Finds a plugin in the available Plugins194/// </summary>195/// <param name="pluginNameOrPath">The name or File path of the plugin to find</param>196/// <returns>Available Plugin, or null if the plugin is not found</returns>197public Types.AvailablePlugin Find(string pluginNameOrPath)198{199Types.AvailablePlugin toReturn = null;200201//Loop through all the plugins202foreach (Types.AvailablePlugin pluginOn in this.List)203{204//Find the one with the matching name or filename205if ((pluginOn.Instance.Name.Equals(pluginNameOrPath)) || pluginOn.AssemblyPath.Equals(pluginNameOrPath))206{207toReturn = pluginOn;208break;209}210}211return toReturn;212}213}214215/// <summary>216/// Data Class for Available Plugin. Holds and instance of the loaded Plugin, as well as the Plugin's Assembly Path217/// </summary>218public class AvailablePlugin219{220//This is the actual AvailablePlugin object..221//Holds an instance of the plugin to access222//ALso holds assembly path... not really necessary223private IPlugin myInstance = null;224private string myAssemblyPath = "";225226public IPlugin Instance227{228get {return myInstance;}229set {myInstance = value;}230}231public string AssemblyPath232{233get {return myAssemblyPath;}234set {myAssemblyPath = value;}235}236}237}238}239