1. Main Program:
Core program, write the necessary parts of the project to the main program.
Take customer management as an example:
In customer management, the customer's basic file management and customer classification management can be regarded as a fixed part of the program, which must also be implemented in the early stage of the program. As the main program part, development is preferred, customers' interests and hobbies. The customer investigates these relatively large changes and can be used as extensions for later development and written as plug-ins.
Here, we only talk about the development and implementation of plug-ins. The rest are not described in detail.
Create a solution: plug-in-type development Customer Management
Create a Windows application project in the solution: CRM
Put it down here and go to the plug-in implementation section.
2. Interface Definition:
Create a class library project in the solution: CRM. iplugin
Create a class in the project: ivote. CS
Code:
using System;namespace CRM.IPlugin{ public interface IVote { void Setup(); string GetPluginName(); }}
3: Compile the plug-in:
Create a class library project in the solution: CRM. plugins
Add reference:
. Net: system. Windows. Forms
Project: CRM. iplugin
Create a form in the project: vote. CS
Form code:
Using system; using system. collections. generic; using system. componentmodel; using system. drawing; using system. text; using system. windows. forms; namespace CRM. plugins {public partial class vote: form, CRM. iplugin. ivote {public vote () {initializecomponent ();} private void vote_load (Object sender, eventargs e) {This. TEXT = "customer voting survey" ;}# region ivote member public void setup () {This. show () ;}public string getpluginname () {return "customer voting survey" ;}# endregion }}
At this point, the plug-in is completed. Find the CRM project folder and create the directory plugins under the bin \ DEBUG directory. Return to the VS solution Resource Manager and select CRM. plugins project, right click-> properties-> Generate-> output directory is set .. \ CRM \ bin \ debug \ plugins \, and generate another CRM. plugins project.
4. Call the plug-in:
Return to project CRM, open the form, drag and drop a ListBox control on the form, switch to the Code view, and enter the following code:
Using system; using system. collections. generic; using system. componentmodel; using system. data; using system. drawing; using system. text; using system. windows. forms; namespace CRM {public partial class form1: FORM {public form1 () {initializecomponent ();} private void form1_load (Object sender, eventargs e) {This. loadplugins ();} // directory for storing the plug-in DLL file private system. collections. arraylist pluginsdll = new syste M. collections. arraylist (); // <summary> // load all plug-ins // </Summary> private void loadplugins () {try {// obtain the Plugins directory file string [] pluginfiles = system. io. directory. getfiles (application. startuppath + @ "\ plugins"); foreach (string pluginfile in pluginfiles) {// The DLL file is a valid plug-in assembly if (pluginfile. toupper (). endswith (". DLL ") {// load the DLL assembly system through reflection. reflection. assembly AB = system. reflection. assembly. loadfrom (Pluginfile); // obtain the class name type [] types = AB. gettypes (); foreach (type T in types) {// check whether the class implements the defined ivote interface if (T. getinterface ("ivote ")! = NULL) {listbox1.items. add (T. fullname); pluginsdll. add (pluginfile) ;}}}} catch (exception ex) {MessageBox. show (ex. message );}} /// <summary> /// call the plug-in method /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void listbox#click (Object sender, eventargs e) {try {If (listbox1.selectedindex =-1) {return;} string plugindllfile = pluginsdll [listbox1.selectedindex]. tostring (); // load the plug-in DLL assembly system. reflection. assembly AB = system. reflection. assembly. loadfrom (plugindllfile); // create the Instance Object plugin which the class named the selected item name in listbox1 is named. createinstance (listbox1.selecteditem. tostring (); Type T = plugin. getType (); // obtain the method getpluginname System in the class. reflection. methodinfo pluginmethodreturnvalue = T. getmethod ("getpluginname"); // execute the method object returnvalue = pluginmethodreturnvalue with a returned value. invoke (plugin, null); MessageBox. show ("the plug-in you called is:" + returnvalue. tostring (); // obtain the method setup system in the class. reflection. methodinfo pluginmethod = T. getmethod ("setup"); // execute the pluginmethod method without return values. invoke (plugin, null);} catch (exception ex) {MessageBox. show (ex. message );}}}}
5. Summary:
Plug-in programming sacrifices the execution efficiency of a part of the program to improve development efficiency. I just have a preliminary understanding.
For this example program, I think the biggest defect is the following:
1. When calling the plug-in method, you need to load the plug-in DLL file and create the corresponding instance each time. There is still a lot of space for performance improvement. You should be able to use the cache to store the created instance, however, I have not mastered the cache under winform, and it is not resolved yet.
2. Each call will open a window. One of the solutions is to check whether the form is in Applicaton in the setup method of the plug-in form call. in OpenForm, the created object will be released if it is not displayed. I think it is not so good. I hope you can provide a better solution.
The Code is as follows. Modify the setup method of the vote form in CRM. plugins:
public void Setup() { System.Windows.Forms.FormCollection FormColl = Application.OpenForms; if (FormColl[this.Name] != null) { (FormColl[this.Name] as Form).WindowState = FormWindowState.Normal; (FormColl[this.Name] as Form).Focus(); this.Dispose(); } else { this.Show(); } }