Plugin architecture using C #

Source: Internet
Author: User
Introduction

This article demonstrates to you how to induplicate ate a single module, as a plugin for another application or use it as a standalone application. the article will demonstrate how a minimal change is required to obtain the above result.

Background

The basic idea for this article has been adopted from the net, I don't remember the original author, but I found the code as a console application, while what I was searching was a method to use one of my windows application module in another application and run it standalone as well with as minimal changes a possible. A little changes to the console application, and this article is what the final result looks like.

Using the code

The key to a plugin architecture is the implementation of a minimal set of methods by the Plugins. these methods are used by the main (inconfigurating) application to find and recognize the Plugins. this minimal set of method is achieved by making an interface, which wowould declare the methods, that are to be implemented by the Plugins. this interface has been defined as follows:

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> IPlugin{    <span class="code-keyword">string</span> Name{<span class="code-keyword">get</span>;<span class="code-keyword">set</span>;}    IPluginHost Host{<span class="code-keyword">get</span>;<span class="code-keyword">set</span>;}    <span class="code-keyword">void</span> Show();}

The interface define a few methods.Name Is used to get the name of the plugin to be shown on the main application in the menu. IPluginHost Is used to let the plugin know who is hosting the plugin.Show Will show the main form of the plugin application.

We now make our first plugin form of a Windows application like this.

<span class="code-keyword">using</span> System;<span class="code-keyword">using</span> PlugIn; <span class="code-keyword">namespace</span> Dynamic{    <span class="code-keyword">class</span> PlugIn : IPlugin    {        <span class="code-keyword">private</span> <span class="code-keyword">string</span> m_strName;        <span class="code-keyword">private</span> IPluginHost m_Host;         <span class="code-keyword">public</span> PlugIn()        {            m_strName = <span class="code-string">"</span><span class="code-string">Dynamic"</span>;         }         <span class="code-keyword">public</span> <span class="code-keyword">string</span> Name        {            <span class="code-keyword">get</span>{<span class="code-keyword">return</span> m_strName;}            <span class="code-keyword">set</span>{m_strName=value;}        }         <span class="code-keyword">public</span> <span class="code-keyword">void</span> Show()        {             Main1 mn = <span class="code-keyword">new</span> Main1();            mn.ShowDialog();        }         <span class="code-keyword">public</span> IPluginHost Host        {            <span class="code-keyword">get</span>{<span class="code-keyword">return</span> m_Host;}            <span class="code-keyword">set</span>            {                m_Host=value;                m_Host.Register(<span class="code-keyword">this</span>);            }        }    }} <span class="code-keyword">public</span> <span class="code-keyword">class</span> Main1 : System.Windows.Forms.Form {     <span class="code-comment">//</span><span class="code-comment">Your original code goes here...</span>    [STAThread]    <span class="code-keyword">static</span> <span class="code-keyword">void</span> Main()     {        Application.Run(<span class="code-keyword">new</span> Main1());    }}

The above Code declare the plugin class so that the parent application cocould recognize it as a plugin. The application also declare a form class, which is the startup form.

Now compile the plugin as an executable file. run it, It shoshould run as a normal standalone exe. copy the EXE into the main applications executable directory, and rename it as a DLL instead of a exe.

Now we move to our main application:

For that we have to interface, which is implemented by our application so that it registers with the Plugins.

    <span class="code-keyword">public</span> <span class="code-keyword">interface</span> IPluginHost    {        <span class="code-keyword">bool</span> Register(IPlugin ipi);    }

The main application is implemented as windows form.

<span class="code-keyword">public</span> <span class="code-keyword">class</span> Form1 : System.Windows.Forms.Form, IPluginHost {    <span class="code-keyword">private</span> System.Windows.Forms.MainMenu mainMenu1;    <span class="code-keyword">private</span> System.Windows.Forms.MenuItem menuItem1; <span class="code-keyword">private</span> IPlugin[] ipi;     <span class="code-keyword">private</span> <span class="code-keyword">void</span> Form1_Load(<span class="code-keyword">object</span> sender, System.EventArgs e)    {        <span class="code-keyword">string</span> path = Application.StartupPath;        <span class="code-keyword">string</span>[] pluginFiles = Directory.GetFiles(path, <span class="code-string">"</span><span class="code-string">*.DLL"</span>);        ipi = <span class="code-keyword">new</span> IPlugin[pluginFiles.Length];         <span class="code-keyword">for</span>(<span class="code-keyword">int</span> i= <span class="code-digit">0</span>; i&lt;pluginFiles.Length; i++)        {            <span class="code-keyword">string</span> args = pluginFiles[i].Substring(                pluginFiles[i].LastIndexOf(<span class="code-string">"</span><span class="code-string">//")+1,                pluginFiles[i].IndexOf("</span>.DLL<span class="code-string">"</span><span class="code-string">)-                pluginFiles[i].LastIndexOf("</span>//<span class="code-string">"</span><span class="code-string">)-1);             Type ObjType = null;            try            {                // load it                Assembly ass = null;                ass = Assembly.Load(args);                if (ass != null)                {                    ObjType = ass.GetType(args+"</span>.PlugIn<span class="code-string">"</span><span class="code-string">);                }            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);            }            try            {                // OK Lets create the object as we have the Report Type                if (ObjType != null)                {                    ipi[i] = (IPlugin)Activator.CreateInstance(ObjType);                    ipi[i].Host = this;                }            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);            }        }    } }</span>

InOnLoad(), We check for all the DLLs present in the application directory, and scan if any implement the plugin interface. if it does we store it and register the plugin with us. this plugin in turn callthe Register Method on the main application. the Register Method Add the plugin name with out menu.

        <span class="code-keyword">public</span> <span class="code-keyword">bool</span> Register(IPlugin ipi)        {            MenuItem mn = <span class="code-keyword">new</span> MenuItem(ipi.Name,<span class="code-keyword">new</span> EventHandler(NewLoad));             Console.WriteLine(<span class="code-string">"</span><span class="code-string">Registered: "</span> + ipi.Name);            menuItem1.MenuItems.Add(mn);            <span class="code-keyword">return</span> <span class="code-keyword">true</span>;        }

The next time the plugin menu is click, we check for the respective plugin name and call the appropriate plugin.

<span class="code-keyword">private</span> <span class="code-keyword">void</span> NewLoad(<span class="code-keyword">object</span> sender, System.EventArgs e) {     MenuItem mn = (MenuItem)sender; <span class="code-keyword">for</span>(<span class="code-keyword">int</span>     i=0; i &lt; ipi.Length; i++)    {        <span class="code-keyword">string</span> strType = mn.Text;        <span class="code-keyword">if</span>(ipi[i]!=null)        {            <span class="code-keyword">if</span>(ipi[i].Name==strType)            {                ipi[i].Show();                <span class="code-keyword">break</span>;            }        }    }            }

Now compile and run the application, with the plugin DLL in the Application Path, the plugin name wocould show in the menu. click the menu and the plugin pops up. hope you find the code useful.

History

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.