外掛架構學習體會(一) -- 宿主程式說:外掛你得聽我的
阿新 • • 發佈:2019-01-22
看了一段時間的#develop,首先接觸到的就是程式的外掛架構。園子裡也有許多不錯的資料可以學習。隨時把自己的認識寫下來和大家交流,無疑會有很大幫助。閒話就不說了,進入正題。
說到外掛架構,首先要有一個整體印象,到底什麼才是外掛架構?這個問題的答案很好找,找個外掛架構的程式看看就可以了,比如VS,MyIE,再比如千千靜聽。我們可以開發不同功能的外掛,載入到宿主程式上,功能就能發揮作用。宿主程式呢,完全不知道我們到底什麼樣的功能,怎麼實現的。這裡呢,我想從我們平常寫程式時引用一些類庫說起。我們經常會把一些功能封裝到一個dll中,然後在其他專案中引用,引用時,直接呼叫其中的方法就ok了。 Dll是編譯過的,方法名是我們自己知道的,無論是自己寫的dll,還是引用別人的,總之,我們一定知道我們呼叫的什麼方法。試想一下,如果我們加一個約定,約定了這個dll中的方法名,那這個時候,這個dll的客戶程式是不是不用管是什麼dll,只要呼叫約定的方法就可以了?那再想一下,這個dll非得引用嗎?動態載入行不行?當然行,載入之後,去呼叫約定的方法,完全可以。到這裡,我們發現,其實只要一個約定,客戶程式完全不需要去在意它的服務者是什麼樣的狀態,exe也好dll也好,只要能提供契約裡的方法就ok了,它只關心有沒有這麼一個方法可以呼叫。至此,發現這不就是最最簡單的一個外掛架構的樣子嗎?
接下來,趕緊動手寫個例子試一下:
首先,定義一個契約,這裡採用了介面,那最好再來一個實現該介面的抽象類,如下 public interface IPlugIn
{
//往控制檯上列印東西,這裡可以寫任何你想要的契約行為
void PrintToConsole();
}
接下來,寫宿主程式,宿主程式肯定要先載入實現了IPlugIn的外掛,然後呼叫其約定的方法。在.Net裡無非就是反射一下就ok了,看程式碼: static void Main(string[] args)
{
List<IPlugIn> PlugIns = LoadPlugIn();
if (PlugIns != null)
{
foreach (IPlugIn p in PlugIns)
{
p.PrintToConsole();
}
}
Console.ReadLine();
}
/// <summary>
/// 載入外掛
/// </summary>
/// <returns>返回可用外掛的列表</returns>
private static List<IPlugIn> LoadPlugIn()
{
List<IPlugIn> Plugs = new List<IPlugIn>();
Assembly a = null;
try
{
a = Assembly.LoadFile(Console.ReadLine());
}
catch
{
Console.WriteLine("File not found!");
return null;
}
System.Type[] types = a.GetTypes();
foreach (System.Type type in types)
{
//校驗載入的dll是否實現了契約,當然此處也可以用Attribute來實現
if (type.GetInterface("IPlugIn") != null)
{
Plugs.Add((IPlugIn)Activator.CreateInstance(type));
}
}
return Plugs;
}
} 下一步,該完成外掛了,實現那個介面而已嘛,簡單 //實現了contract里約定的方法,控制檯上輸出"Hello world"字串
public void PrintToConsole()
{
Console.WriteLine("Hello world!");
} 測試一下,為了方便,我把外掛dll copy到G盤根目錄下(可以少打幾個字母哦),執行宿主程式,輸入該dll路徑,看到了我們預期的hello world
程式碼地址:http://files.cnblogs.com/Pcant/SimplePlug-in.rar (待續)
園子裡相關資源推薦:
http://www.cnblogs.com/guanjinke/archive/2007/03/14/675109.html
http://www.cnblogs.com/wayfarer/articles/28537.html
說到外掛架構,首先要有一個整體印象,到底什麼才是外掛架構?這個問題的答案很好找,找個外掛架構的程式看看就可以了,比如VS,MyIE,再比如千千靜聽。我們可以開發不同功能的外掛,載入到宿主程式上,功能就能發揮作用。宿主程式呢,完全不知道我們到底什麼樣的功能,怎麼實現的。這裡呢,我想從我們平常寫程式時引用一些類庫說起。我們經常會把一些功能封裝到一個dll中,然後在其他專案中引用,引用時,直接呼叫其中的方法就ok了。
接下來,趕緊動手寫個例子試一下:
首先,定義一個契約,這裡採用了介面,那最好再來一個實現該介面的抽象類,如下
{
//往控制檯上列印東西,這裡可以寫任何你想要的契約行為
void PrintToConsole();
}
接下來,寫宿主程式,宿主程式肯定要先載入實現了IPlugIn的外掛,然後呼叫其約定的方法。在.Net裡無非就是反射一下就ok了,看程式碼: static void Main(string[] args)
{
List<IPlugIn> PlugIns = LoadPlugIn();
if (PlugIns
{
foreach (IPlugIn p in PlugIns)
{
p.PrintToConsole();
}
}
Console.ReadLine();
}
/// <summary>
/// 載入外掛
/// </summary>
/// <returns>返回可用外掛的列表</returns>
private static List<IPlugIn> LoadPlugIn()
{
List<IPlugIn> Plugs = new List<IPlugIn>();
Assembly a = null;
try
{
a = Assembly.LoadFile(Console.ReadLine());
}
catch
{
Console.WriteLine("File not found!");
return null;
}
System.Type[] types = a.GetTypes();
foreach (System.Type type in types)
{
//校驗載入的dll是否實現了契約,當然此處也可以用Attribute來實現
if (type.GetInterface("IPlugIn") != null)
{
Plugs.Add((IPlugIn)Activator.CreateInstance(type));
}
}
return Plugs;
}
} 下一步,該完成外掛了,實現那個介面而已嘛,簡單 //實現了contract里約定的方法,控制檯上輸出"Hello world"字串
public void PrintToConsole()
{
Console.WriteLine("Hello world!");
} 測試一下,為了方便,我把外掛dll copy到G盤根目錄下(可以少打幾個字母哦),執行宿主程式,輸入該dll路徑,看到了我們預期的hello world
程式碼地址:http://files.cnblogs.com/Pcant/SimplePlug-in.rar (待續)
園子裡相關資源推薦:
http://www.cnblogs.com/guanjinke/archive/2007/03/14/675109.html
http://www.cnblogs.com/wayfarer/articles/28537.html