接口
接口是插件行為的描述。 接口不包括任何業務邏輯實現,業務邏輯包含在實現接口的類中。
接口聲明:
public interface IPlus
{
///<summary>
///插件行為方法
///</summary>
void DoSomething();
}
類的實現:
public class Plus1: IPlus
{
#region IPlus成員
void IPlus.DoSomething()
{
MessageBox.Show(GetType().ToString() + " Do somthing...");
}
#endregion
}
插件化系統中提倡通過接口的方式來訪問對象,也可以使用虛基類來實現整個系統。使用接口和使用類,在業界也是經常引起爭議的話題,筆者比較推薦用接口來實現。
反射
反射主要理解為在未能引用類的類型定義情況下創建和訪問對象的能力。
名字空間Kaitu.System中包含了Form類。 一般情況下當需要創建一個Form類的對象時, 必須引用Kaitu.System命名空間, 然后聲明Form類型的對象,然后用new操作創建對象。
Form frm = new Form(); //一般類對象的創建。
假如Form類的定義暫時不能引用到當前的開發環境下 , 但時程序在運行期卻是能創建并訪問它, 這個時候就要利用反射機制來創建該對象:
比如:
using System.Reflection;
//加載運行期的程序集。
Assembly SampleAssembly = Assembly.LoadFile(@"c:\kaitulib.dll");
//創建程序集中包含的類對象。
object instance = SampleAssembly.CreateInstance("Guost.Lib.PlusA");
首先是通過程序集的文件名加載程序集對象, 這里類似設計期對程序集的引用。然后是通過類的名稱字符串創建類對象,從這里可以看出,創建一個類對象不再用new的方式,而是通過程序集名稱和類名字符串創建的。 這里可能有人要問,既然不引用程序集,那么怎樣訪問創建后的對象呢?用接口,反射創建的類對象都實現了接口,而接口我們在應用程序設計期是可見的。
IPlus myPlusObject = instance as IPlus; //將對象轉到接口
MyPlusObject.DoSomething(); //調用業務邏輯
using System.Data;2
using System.IO;3
using System.Drawing;4
using MyInterface;5
using System.Text;6
using System.Windows.Forms;7
using System.Reflection;8

9
namespace pathTest10


{11
public partial class Form1 : Form12

{13
public Form1()14

{15
InitializeComponent();16
}17
private Dictionary<String, inter> plusList = new Dictionary<string, inter>();18
private void Form1_Load(object sender, EventArgs e)19

{20

找路徑#region 找路徑21
String path = Application.StartupPath + @"\plusTest";22
textBox1.Text = path;23
#endregion24

創建目錄#region 創建目錄25
DirectoryInfo dirInfo = new DirectoryInfo(path);26
#endregion27

遍歷目錄所有文件提取目的dll中的類型#region 遍歷目錄所有文件提取目的dll中的類型28
FileInfo[] fileInfos = dirInfo.GetFiles();29
foreach (FileInfo fi in fileInfos)30

{31
if (fi.Extension.Equals(".dll") && fi.FullName.IndexOf("testLib") != -1)32

{33
Assembly SampleAssembly;34
try35

{36
SampleAssembly = Assembly.LoadFile(fi.FullName);37
Type[] objType = SampleAssembly.GetTypes();38

反射機制創建對象#region 反射機制創建對象39
//反射機制創建對象40
for (int i = 0; i < objType.Length; i++)41

{42
this.listBox1.Items.Add(objType[i].ToString());43

44
object plus = SampleAssembly.CreateInstance(objType[i].ToString());45
//把對象轉嫁為接口46

把對象轉嫁為接口#region 把對象轉嫁為接口47
inter myinter = plus as inter;48
plusList.Add(objType[i].ToString(), myinter);49
# endregion50

51
}52
#endregion53
}54
catch (Exception ex)55

{56
MessageBox.Show(ex.Message,"提示信息");57
}58

59
}60
}61
#endregion62

63
}64

65
private void listBox1_Click(object sender, EventArgs e)66

{67
string key = listBox1.Items[this.listBox1.SelectedIndex].ToString();68
inter myinter = plusList[key];69
textBox2.Text = myinter.Show();70
}71
}72
}以下是兩個dll. 一個是MyInterface.dll, 一個是TestLib.dll.其中MyInterface.dll是主程序框架中寫好后編譯成dll后暴露給插件編程者的,插件編程者引用該dll.另一個TestLib.dll.以插件的形式給出,不需要程序里引用,通過程序集對象的CreatInstance( classname )方法來創建對象實例,創建好的對象實例轉到接口然后調用接口中的行為。
bject plus = SampleAssembly.CreateInstance(objType[i].ToString());
inter myinter = plus as inter;
using System;2
using System.Collections.Generic;3
using System.Text;4

5

6
namespace MyInterface7


{8
public interface inter9

{10
String Show();11
}12
}
using System;2
using System.Collections.Generic;3
using System.Text;4
using MyInterface;5

6
namespace testLib7


{8
public class Family:inter9

{10
String motherName = "miaomiao";11
String fatherName = "fox";12
String sisterName = "big cat";13
String myselfName = "hehe";14

15
public String MotherName16

{17

get
{ return motherName; }18

set
{ motherName = value; }19
}20
public String FatherName21

{22

get
{ return fatherName; }23

set
{ fatherName = value; }24
}25
public String SisterName26

{27

get
{ return sisterName; }28

set
{ sisterName = value; }29
}30
public String MyselfName31

{32

get
{ return myselfName; }33

set
{ myselfName = value; }34
}35
36
public Family()37

{ }38
String inter.Show()39

{40
String res = "Mother:" + motherName + ",Father:" + fatherName + ",Sister:" + sisterName + ",And Me " + myselfName;41
return res;42
}43
}44

45
public class BFriend:inter46

{47
String bfName = "tutu";48
String myName = "miaomiao";49
public String BfName50

{51

get
{ return bfName; }52

set
{ bfName = value; }53
}54
public String MyName55

{56

get
{ return myName; }57

set
{ myName = value; }58
}59
public BFriend()60

{61
62
}63
String inter.Show()64

{65
String res = bfName + " like " + myName + ",and " + myName + " like " + bfName;66
return res;67
}68
}69
}70



