給IBuySpy構建一個PlugIn系統
2024-07-21 02:15:48
供稿:網友
本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。話說公元2003年12月17日,msdn library網站上悄無聲息的多了一篇文章,介紹了關于構建一個plugin framework的一些基礎知識,于是,有了這篇隨筆…
plugin,很cool的特性,下面將演示如何給我們的ibuyspy定制一個page start plugin,這個plugin可以讓用戶自己來創建plugin,嵌入到ibuyspy的page start plugin里面,在網站頁面載入的時候,會執行用戶嵌入的plugin。
可我們為什么要給ibuyspy創建plugin接口呢?我們要實現同樣的功能,可以直接的修改它的代碼,豈不是直接很多?原因:ibuyspy只是用來演示plugin的,你可以把同樣的技術應用到其他的webform甚至winform,而它們可能并不會像ibuyspy一樣是免費的,我們交付的產品里面不會附上代碼,如果我們提供了plugin的接口,無疑會讓我們的產品更加具有擴展性。何況很多功能可能可以直接作成plugin來嵌入到原有的系統中,這個時候無需再改動原有的代碼,再去編譯它。
1、構建ibuyspy的plugin所需的接口,這些接口就是可以公開給用戶代碼的:
首先需要的是一個通用的iplugin接口,所有具體的插件將實現這個接口:
namespace aspnetportal.plugins {
public interface iplugin {
string name {get;}
string version {get;}
void doaction(ipluginargs args);
}
}
這個接口有三個成員:
name屬性,公開插件的名稱
version屬性,公開插件的版本
doaction()方法,執行插件要做的操作,這個方法還有一個ipluginargs的參數,需要傳遞給方法所參數可以通過它傳遞出去。
然后就是這個ipluginargs接口:
namespace aspnetportal.plugins {
public interface ipluginargs {
system.web.httpcontext context {get;}
object data {get;}
}
}
它有兩個成員:
context屬性,一個httpcontext類型的對象,如果我們要讓插件能夠在頁面上做些事,不給它httpcontext肯定不行。
data屬性,一個object類型的對象,預留的,什么地方需要就什么地方用上。
接著是一個接口集合類:
namespace aspnetportal.plugins {
public class plugincollection : collectionbase {
public int32 add(iplugin plugin) {
return this.list.add(plugin);
}
public iplugin this[int32 index] {
get {
return (iplugin) this.list[index];
}
}
}
}
很簡單明了。用戶可能不止嵌入一個插件。
plugin也可以有很多類型,比如我們這里要實現的page start plugin,是一個在頁面載入的時候可以讓嵌入的plugin執行的。當然你也可以創建各種類型的plugin。
namespace aspnetportal.plugins {
public interface ipagestartplugin : iplugin {}
}
這個plugin接口不需要再做任何事,直接繼承iplugin就可以了。
2、修改ibuyspy,讓它支持執行plugin:
根據我們的需求,我們創建一個實際的插件參數類,這個類繼承自ipluginargs:
namespace aspnetportal.plugins {
public class pluginargs : ipluginargs {
private system.web.httpcontext _context;
private object _data;
public pluginargs(system.web.httpcontext context, object data) {
_context = context;
_data = data;
}
public system.web.httpcontext context {
get {
return _context;
}
}
public object data {
get {
return _data;
}
}
}
}
我們需要地方來標示用戶嵌入的plugin的列表,我們放在web.config里面的里面,我們加上一項,來表示我們要添上的page start plugin:
《add key="pagestartplugins" value="" /》
value里面可以寫入嵌入的plugin的列表,格式像這樣:value = "插件一的類名, 插件一的程序集名; 插件二的類名, 插件二的程序集名"
然后,我們構建一個pluginhelper類,來執行獲取plugin、執行plugin的操作:
namespace aspnetportal.plugins {
public class pluginhelper {
private pluginhelper() {}
public static plugincollection getplugins(string plugintype) {
plugincollection plugins = new plugincollection();
string spagestartplugins = system.configuration.configurationsettings.appsettings[plugintype];
if ((spagestartplugins != null) && (spagestartplugins != "")) {
string[] aspluginstr = spagestartplugins.split(';'); foreach(string pluginstr in aspluginstr) {
plugins.add( (ipagestartplugin) system.activator.createinstance(system.type.gettype(pluginstr)));
}
}
return plugins;
}
public static void executeplugins(plugincollection plugins, ipluginargs args) {
foreach(iplugin plugin in plugins) {
plugin.doaction(args);
}
}
}
}
getplugins()方法返回指定類型的plugin的列表,返回類型是plugincollection,executeplugins()用來執行參數中的plugin。
最后,我們要把執行插件的代碼加入到頁面的執行隊列中。為了在每個頁面開始的時候能夠執行用戶嵌入的page start plug,標準方法是在global.asa里面來實現,更標準的方法是構建一個httpmodule,然后在這個httpmodule中來執行這個plugin(關于構建自定義的httpmodule,辣椒是個中高手)。我這里就偷懶了,因為ibuyspy幾乎所有的內容頁面都是desktopdefault.aspx這個頁面中載入,所以我們先在這個頁面里面創建一個方法來執行插件:
private void performplugins() {
plugincollection plugins = pluginhelper.getplugins("pagestartplugins");
pluginargs args = new pluginargs(context, null);
pluginhelper.executeplugins(plugins, args);
}
第一句得到所有的page start plugin,第二句創建一個傳遞給插件的pluginargs對象,第三句調用pluginhelper.executeplugins()來執行第一句得到的plugin隊列。
在desktopdefault.aspx的page_init事件中調用上面的這個performplugins()方法就ok了。
3、演示如何創建一個page start plugin:
前面兩步已經讓ibuyspy可以嵌入用戶自定義的page start plugin了,現在我們來做一個實際的plugin嵌進去。
啟動vs,創建一個“c#類庫”項目,引入ibuyspy的程序集portal.dll,這是因為我們需要用到ibuyspy里面的plugin相關的那些接口,更好的方法是把ibuyspy中與plugin相關的公共接口放在一個單獨的程序集里面。
namespace welcomemessage {
public class showwelcome : aspnetportal.plugins.ipagestartplugin {
public string name {
get {
return "show page welcome message";
}
}
public string version {
get {
return "1.0.0.1";
}
}
public void doaction(ipluginargs args) {
args.context.response.write(“<_script_>alert(‘hello, world!’);”); // 故意寫錯了,不然...
}
}
}
這個showwelcome類繼承自ipagestartplugin,表示它是一個page start plugin,用來具體執行操作的doaction()方法只做了一件事,從參數中得到頁面相關的httpcontext對象,然后輸出一段字符以在頁面內容載入之前彈出一個“hello,world!”的提示框。
然后我們修改ibuyspy的web.config里面相關的那句設定:
《add value="welcomemessage.showwelcome, welcomemessage" key="pagestartplugins" /》
ok了,編譯,把生成的dll放到ibuyspy的bin目錄,打開瀏覽器瀏覽ibuyspy網站,你會看到每次載入頁面內容時,都會彈出一個“hello,world!”的提示框。