自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺析C#插件式程序開(kāi)發(fā)經(jīng)驗(yàn)

開(kāi)發(fā) 后端
本文作者將給大家分享一下C#插件式程序開(kāi)發(fā)經(jīng)驗(yàn),在共同討論的過(guò)程中能共同進(jìn)步。

在網(wǎng)上找了下插件式編程的資料,這里自己先借鑒下別人的,同時(shí)發(fā)現(xiàn)有自己的看法,不過(guò)由于本人水平有限,不一定有參考價(jià)值,寫(xiě)出來(lái)一方面是為了總結(jié)自己,以求提高,另一方面也希望各為朋友看到我的不足,給我提出寶貴意見(jiàn)。

什么是插件式編程

提起插件式,我們首先想到的是firefox,用過(guò)firefox的人都知道它是一個(gè)插件式程序。當(dāng)一個(gè)功能需要,完全可以從網(wǎng)上下載一個(gè)插件后,重啟后,就能使用。這個(gè)功能給我們帶來(lái)許多的方便之處,這就是插件式程序的好處。

插件的本質(zhì)在于不修改程序主體(平臺(tái))的情況下對(duì)軟件功能進(jìn)行拓展與加強(qiáng),當(dāng)插件的接口公開(kāi)后,任何公司或個(gè)人都可以制作自己的插件來(lái)解決一些操作上的不便或增加新功能,也就是真正意義上實(shí)現(xiàn)“即插即用”軟件開(kāi)發(fā)。

平臺(tái)+插件軟件結(jié)構(gòu)是將一個(gè)待開(kāi)發(fā)的目標(biāo)軟件分為兩部分,一部分為軟件的主體或框架,可定義為平臺(tái),這是預(yù)先編譯后的程序。另一部分為功能或補(bǔ)充模塊,可定義為插件。這個(gè)就是后來(lái)要進(jìn)行安裝的插件程序。

假設(shè)你的程序已經(jīng)部署在用戶(hù)的計(jì)算機(jī)上,并且能夠正常運(yùn)行了。但是有一天,用戶(hù)打來(lái)電話——他們需要增加新的功能。確定了用戶(hù)的需求后,你竟然發(fā)現(xiàn)原有的軟件架構(gòu)已經(jīng)無(wú)法勝任新增任務(wù)的需求——你需要重新設(shè)計(jì)這個(gè)應(yīng)用了!但問(wèn)題是,就算你又用了一個(gè)開(kāi)發(fā)周期完成了用戶(hù)需要的應(yīng)用,切不能保證用戶(hù)的需求不會(huì)再次變更。也就是說(shuō),需求蔓延的可能性依然存在。因此,這種情況下插件架構(gòu)更能顯示出它的優(yōu)越性。

可以這么說(shuō),用它可以帶來(lái)方便的地方,而且開(kāi)發(fā)它,也很簡(jiǎn)單。而且這樣的主程序根本就不需要改動(dòng)。需要插件時(shí),拿來(lái)就能用,插件更新時(shí),也只需更新這個(gè)插件即可。

從程序開(kāi)發(fā)這角度,一般是先開(kāi)發(fā)主程序,決定哪些功能由主程序來(lái)完成,然后再建立接口,申明接口的內(nèi)容,這些內(nèi)容決定著插件功能的擴(kuò)展,及方向的。這些都是有主程序開(kāi)發(fā)者預(yù)先準(zhǔn)備好的。插件開(kāi)發(fā)者,從主程序開(kāi)發(fā)者那里得到接口的內(nèi)容,并書(shū)寫(xiě)繼承這些接口的類(lèi),來(lái)完成具體的功能。

下面來(lái)寫(xiě)個(gè)例子,這個(gè)例子沒(méi)實(shí)際意義,純屬學(xué)習(xí)思想。例子是網(wǎng)上的經(jīng)過(guò)自己改造的,發(fā)現(xiàn)別人某些地方不合理。

首先,新建一個(gè)類(lèi)庫(kù),里面定義接口,這里定義兩個(gè)方法,一個(gè)有返回值的,一個(gè)無(wú)返回值的。

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. namespace IMsg{     
  5.  /// <summary>     
  6.  /// 這是插件必須實(shí)現(xiàn)的接口,也是主程序與插件通信的***接口      
  7. /// 換句話說(shuō),主程序只認(rèn)識(shí)插件里的這些方法     
  8.  /// </summary>  public  interface IMsgPlug     
  9.  {         
  10.  void OnShowDlg();      
  11.     string OnShowInfo();   
  12.    }} 

將上面的類(lèi)庫(kù)生成IMsg.dll,新建一個(gè)類(lèi)庫(kù)MYPlugin1,添加剛出的引用,分別新建兩個(gè)類(lèi)來(lái)實(shí)現(xiàn)IMsg中定義的接口。

  1. using System;  
  2. using System.Collections.Generic;using System.Text;using IMsg;  
  3. namespace MYPlugin1{      
  4. public class myConsole : IMsgPlug     
  5.  {         
  6.  #region IMsgPlug 成員         
  7.  public  void OnShowDlg()       
  8.    {           
  9.    Console.WriteLine("控制臺(tái)調(diào)用插件的OnShowDlg方法");       
  10.    }      
  11.     public  string OnShowInfo()      
  12.     {            return "myConsole";      
  13.     }        #endregion    
  14.   }}  
  15. using System;  
  16. using System.Collections.Generic;  
  17. using System.Text;  
  18. using System.Windows.Forms;  
  19. using IMsg;namespace MYPlugin1{   
  20. public  class MYDlg:Form,IMsgPlug     
  21.  {        #region IMsgPlug 成員   
  22.        public  void OnShowDlg()     
  23.      {           
  24.  this.Text = "插件子窗體";          
  25.   this.ShowDialog();  
  26. //調(diào)用Form的ShowDialog,顯示窗體        }       
  27.    public  string OnShowInfo()    
  28.       {            return "MyDlg";       
  29.    }        #endregion    
  30.   }} 

將上面的都生成dll,生成目錄可以設(shè)置為新建exe工程的bin目錄plugins文件夾下。Plugins文件夾是新建的,專(zhuān)門(mén)存放插件的。 新建一個(gè) WinForm項(xiàng)目,來(lái)使用剛才的插件.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.IO;
using System.Reflection;
namespace MsgBoxMain
{
public partial class FormMain : Form
{

/// <summary>
/// 存放插件的集合
/// </summary>
private ArrayList plugins = new ArrayList();
public FormMain()
{
InitializeComponent();
}

/// <summary>
/// 載入所有插件
/// </summary>
private void LoadAllPlugs()
{
//獲取插件目錄(plugins)下所有文件
string[] files = Directory.GetFiles(Application.StartupPath + @"\plugsins");
foreach (string file in files)
{
if (file.ToUpper().EndsWith(".DLL"))
{
try
{
//載入dll
Assembly ab = Assembly.LoadFrom(file);
Type[] types
= ab.GetTypes();
foreach (Type t in types)
{
//如果某些類(lèi)實(shí)現(xiàn)了預(yù)定義的IMsg.IMsgPlug接口,則認(rèn)為該類(lèi)適配與主程序(是主程序的插件)
if (t.GetInterface("IMsgPlug")!=null)
{
plugins.Add(ab.CreateInstance(t.FullName));
listBox1.Items.Add(t.FullName);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

}



private void btnLoadPlug_Click(object sender, EventArgs e)
{
LoadAllPlugs();
}

//調(diào)用插件的方法
private void btnExecute_Click(object sender, EventArgs e)
{
if (this.listBox1.SelectedIndex == -1) return;
object selObj = this.plugins[this.listBox1.SelectedIndex];
Type t
= selObj.GetType();
MethodInfo OnShowDlg
= t.GetMethod("OnShowDlg");
MethodInfo OnShowInfo
= t.GetMethod("OnShowInfo");

OnShowDlg.Invoke(selObj,
null);
object returnValue = OnShowInfo.Invoke(selObj, null);
this.lblMsg.Text = returnValue.ToString();

}
}
}

 

運(yùn)行結(jié)果:

這里與網(wǎng)上那位原創(chuàng)的仁兄的看法不同(原文鏈接http://blog.csdn.net/jam12315/archive/2008/08/18/2791534.aspx),可供大家討論。

原文有這樣的一段:

if (itemStr == "myConsole")
{ //調(diào)用存儲(chǔ)在動(dòng)態(tài)數(shù)組plugins里面的插件對(duì)象的OnShowInfo方法
string msgInfo = ((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowInfo();
MessageBox.Show(msgInfo, "MYPlugin1", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else if (itemStr == "MYDlg")//調(diào)用存儲(chǔ)在動(dòng)態(tài)數(shù)組plugins里面的插件對(duì)象的OnShowDlg方法
{
((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowDlg();
}

我認(rèn)為既然是插件,就應(yīng)該是動(dòng)態(tài)加載的,客戶(hù)端肯定不能判斷 itemStr,因?yàn)閷?shí)現(xiàn)接口的類(lèi)是不可預(yù)料的,因此主程序不應(yīng)該添加對(duì)IMsg的引用,也不應(yīng)該在客戶(hù)端實(shí)例化插件對(duì)象,因?yàn)椴寮_(kāi)發(fā)的初衷是為了以后更新的時(shí)候不更改主程序,只提供對(duì)應(yīng)的dll 下載,就可以直接使用了,以前的接口都定義好了,新的實(shí)現(xiàn)類(lèi)也就是不可預(yù)料的,因此不能在主程序?qū)嵗瘜?shí)現(xiàn)接口的類(lèi),這樣違背了插件的初衷。

原文鏈接:http://www.cnblogs.com/sndnnlfhvk/archive/2011/06/02/2067713.html

【編輯推薦】

  1. C#簡(jiǎn)單游戲外掛制作(以Warcraft Ⅲ為例)
  2. C#控件的閃爍問(wèn)題解決方法總結(jié)
  3. 淺析C#延遲加載的運(yùn)行機(jī)制和應(yīng)用場(chǎng)景
  4. C#多線程中l(wèi)ock的用法
  5. 用C#實(shí)現(xiàn)HTTP協(xié)議下的多線程文件傳輸
責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2009-09-02 15:34:37

C#實(shí)現(xiàn)插件構(gòu)架

2009-08-24 15:50:23

C# 泛型C# 泛型委托

2009-08-24 09:55:24

C#集成開(kāi)發(fā)環(huán)境

2009-08-28 16:03:15

C#程序?qū)崿F(xiàn)鼠標(biāo)移動(dòng)

2009-08-14 11:00:16

C#創(chuàng)建Windows

2009-08-27 14:29:28

顯式實(shí)現(xiàn)接口

2009-09-07 14:52:01

C# HTTP Req

2009-09-07 14:00:57

C#抓取網(wǎng)頁(yè)

2009-08-24 16:02:10

C# Windows應(yīng)

2009-08-14 17:45:52

C# ArrayLis

2009-08-17 18:34:50

C# ChangeCo

2009-09-11 10:41:20

C# WinForm控

2009-08-07 17:25:37

C# SortedLi

2009-08-25 17:59:49

C#入門(mén)

2009-08-25 09:39:21

創(chuàng)建C# Window

2009-09-03 13:48:46

C#調(diào)用記事本記事本程序

2009-09-02 17:28:26

C#程序設(shè)計(jì)Windows窗體

2009-08-21 15:06:27

C#網(wǎng)絡(luò)聊天程序

2009-08-14 16:41:22

C#啟動(dòng)Windows

2009-08-14 14:25:09

Windows服務(wù)程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)