日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

【转载】基于ASP.NET Web Application的插件实现,附DEMO

發(fā)布時(shí)間:2025/7/14 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转载】基于ASP.NET Web Application的插件实现,附DEMO 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最近的項(xiàng)目中涉及到Asp.Net擴(kuò)展性,考慮了兩種擴(kuò)展方法,一種是使用Web Services實(shí)現(xiàn),另一種是動(dòng)態(tài)生成代碼然后利用反射來(lái)實(shí)現(xiàn)插件功能。現(xiàn)在網(wǎng)上博客什么的都是用插件的形式來(lái)擴(kuò)展功能的,所以我也打算用插件來(lái)擴(kuò)展asp.net網(wǎng)站的功能。

??? 使用插件機(jī)制來(lái)擴(kuò)展B/S程序,主要需要實(shí)現(xiàn)兩個(gè)功能,首先是動(dòng)態(tài)編譯插件中的C#代碼,然后利用反射來(lái)執(zhí)行插件已經(jīng)編譯的C#代碼。

???

??? 一、動(dòng)態(tài)編譯

??? 插件一般是以xml文件的形式實(shí)現(xiàn)其配置,必須要先讀取插件中的C#代碼才能進(jìn)行動(dòng)態(tài)編譯。

XmlDocument?doc?=?new?XmlDocument();?
try?
{?
????
//獲取插件配置文件?
????doc.Load(Server.MapPath(@"plugins/"?+?strPluginName?+?"/config.xml"));?
}
?
catch?(Exception?e)?
{?
????Response.Write(
"插件載入錯(cuò)誤:"?+?e.ToString());?
????
return;?
}
?
XmlNode?xn?
=?doc.DocumentElement.SelectSingleNode("csharpcode");?
string?code?=?string.Empty;?
if?(xn?!=?null)?
{?
????XmlElement?xe?
=?(XmlElement)xn;?
????
if?(xe.HasAttribute("link"))?
????
{?
XmlDocument?doc?
=?new?XmlDocument();?
try?
{?
????
//獲取插件配置文件?
????doc.Load(Server.MapPath(@"plugins/"?+?strPluginName?+?"/config.xml"));?
}
?
catch?(Exception?e)?
{?
????Response.Write(
"插件載入錯(cuò)誤:"?+?e.ToString());?
????
return;?
}
?
XmlNode?xn?
=?doc.DocumentElement.SelectSingleNode("csharpcode");?
string?code?=?string.Empty;?
if?(xn?!=?null)?
{?
????XmlElement?xe?
=?(XmlElement)xn;?
????
if?(xe.HasAttribute("link"))?
????
{?
using?(?
????????????StreamReader?sr?
=?
????????????????System.IO.File.OpenText(?
????????????????????Path.Combine(?
????????????????????????Server.MapPath(
@"plugins/"?+?strPluginName?+?"/"),?xe.GetAttribute("link")?
????????????????????)?
????????????????)?
?????????)?
????????
{?
????????????code?
=?sr.ReadToEnd();?
????????????sr.Close();?
????????}
?
????}
?
????
else?
????
{?
????????code?
=?xe.InnerText;?
????}
?
}
復(fù)制代碼

?

?.Net為我們提供了很強(qiáng)大的支持來(lái)實(shí)現(xiàn)這一切我們可以去做的基礎(chǔ),主要應(yīng)用的兩個(gè)命名空間是:System.CodeDom.Compiler和Microsoft.CSharp或Microsoft.VisualBasic。另外還需要用到反射來(lái)動(dòng)態(tài)執(zhí)行你的代碼。動(dòng)態(tài)編譯并執(zhí)行代碼的原理其實(shí)在于將提供的源代碼交予CSharpCodeProvider來(lái)執(zhí)行編譯(其實(shí)和CSC沒(méi)什么兩樣),如果沒(méi)有任何編譯錯(cuò)誤,生成的IL代碼會(huì)被編譯成DLL存放于于內(nèi)存并加載在某個(gè)應(yīng)用程序域(默認(rèn)為當(dāng)前)內(nèi)并通過(guò)反射的方式來(lái)調(diào)用其某個(gè)方法或者觸發(fā)某個(gè)事件等。之所以說(shuō)它是插件編寫(xiě)的一種方式也正是因?yàn)榕c此,我們可以通過(guò)預(yù)先定義好的借口來(lái)組織和擴(kuò)展我們的程序并將其交還給主程序去觸發(fā)。一個(gè)基本的動(dòng)態(tài)編譯并執(zhí)行代碼的步驟包括:

將要被編譯和執(zhí)行的代碼讀入并以字符串方式保存
聲明CSharpCodeProvider對(duì)象實(shí)例
調(diào)用CSharpCodeProvider實(shí)例的CompileAssemblyFromSource方法編譯
用反射生成被生成對(duì)象的實(shí)例(Assembly.CreateInstance
調(diào)用其方法

以下代碼片段包含了完整的編譯和執(zhí)行過(guò)程:

CodeSnippetCompileUnit?unit?=?new?CodeSnippetCompileUnit(code);?
ICodeCompiler?compiler?
=?new?CSharpCodeProvider().CreateCompiler();?
CompilerParameters?para?
=?new?CompilerParameters();?
para.ReferencedAssemblies.Add(
"System.dll");?
para.ReferencedAssemblies.Add(
"System.Data.dll");?
para.ReferencedAssemblies.Add(
"System.XML.dll");?
para.ReferencedAssemblies.Add(
"System.Drawing.dll");?
para.ReferencedAssemblies.Add(
"System.Web.dll");?
para.ReferencedAssemblies.Add(Server.MapPath(
this.Request.ApplicationPath?+?"/bin/PluginDemo.dll"));?
para.GenerateExecutable?
=?false;?
para.OutputAssembly?
=?dllPath;?
?
//編譯結(jié)果?
CompilerResults?cr?=?compiler.CompileAssemblyFromDom(para,?unit);?
if?(cr.Errors.Count?>?0)?
{?
????Response.Write(
"插件安裝失敗,編譯錯(cuò)誤:<br/>");?
????
//遍歷編譯錯(cuò)誤?
????foreach?(System.CodeDom.Compiler.CompilerError?ce?in?cr.Errors)?
????
{?
????????Response.Write(ce.ErrorText?
+?"(文件:"?+?ce.FileName?+?",行號(hào):"?+?ce.Line.ToString()?+?",錯(cuò)誤編號(hào):"?+?ce.ErrorNumber?+?")<br/>");?
????}
?
????
return;?
}
復(fù)制代碼

???? 了解更多的關(guān)于動(dòng)態(tài)編譯的知識(shí)

這里引用了? System.CodeDom和System.CodeDom.Compiler。

讀取插件中的C#代碼并進(jìn)行動(dòng)態(tài)編譯后,要實(shí)現(xiàn)插件功能,就需要執(zhí)行已經(jīng)編譯好的插件的dll中的代碼了。

??? 二、利用反射實(shí)現(xiàn)插件功能

??? 反射的原理這里就不再說(shuō)了,三層架構(gòu)中用的太多了,呵呵。

public?string?GetPluginOutPut(string?strPluginName)?
{?
????
try?
????
{?
????????
//載入插件程序集?
????????System.Xml.XmlDocument?doc?=?new?System.Xml.XmlDocument();?
????????doc.Load(Server.MapPath(
"plugins/installedplugins.xml"));?
?
????????
string?asmName?=?((System.Xml.XmlElement)doc.DocumentElement.SelectSingleNode("plugin[@name='"?+?strPluginName?+?"']")).GetAttribute("assembly");?
?
????????System.Reflection.Assembly?asm?
=?System.Reflection.Assembly.LoadFrom(Server.MapPath(@"plugins/bin/"?+?asmName));?
????????IPlugin?plugin?
=?(IPlugin)asm.CreateInstance("PluginDemo.plugins."?+?strPluginName);?
?
????????
return?plugin.GetOutput(this);?
????}
?
????
catch?(Exception?ex)?
????
{?
????????
return?"插件‘"?+?strPluginName?+?"’載入失敗:"?+?ex.ToString();?
????}
?
}
復(fù)制代碼

?

?忘了說(shuō)一下,要實(shí)現(xiàn)反射,我們需要先在網(wǎng)站中定義好的一個(gè)IPlugin接口

/**////?<summary>?
///?插件接口?
///?</summary>?

public?interface?IPlugin?
{?
????
/**////?<summary>?
????
///?獲取插件輸出的內(nèi)容?
????
///?</summary>?
????
///?<param?name="page">System.Web.UI.Page</param>?
????
///?<returns>字符串</returns>?

????string?GetOutput(Page?page);?
?
????
/**////?<summary>?
????
///?安裝插件時(shí)執(zhí)行的代碼?
????
///?</summary>?
????
///?<param?name="page">System.Web.UI.Page</param>?

????void?Install(Page?page);?
?
????
/**////?<summary>?
????
///?卸載插件時(shí)執(zhí)行的代碼?
????
///?</summary>?
????
///?<param?name="page">System.Web.UI.Page</param>?

????void?Uninstall(Page?page);?
?
????
/**////?<summary>?
????
///?更新插件時(shí)執(zhí)行的代碼?
????
///?</summary>?
????
///?<param?name="page">System.Web.UI.Page</param>?

????void?Update(Page?page);?
}
復(fù)制代碼

?

?

然后所有的插件的C#代碼都繼承自這一個(gè)接口。

還是把我做的DEMO發(fā)上來(lái)吧,講的不好,大家還是看源碼吧,里面都有注釋,呵呵。


下載地址:http://www.box.net/shared/a2ceqq67ts?

總結(jié)

以上是生活随笔為你收集整理的【转载】基于ASP.NET Web Application的插件实现,附DEMO的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美亚洲图片小说 | 久久人人爽人人爽人人片av免费 | 国产欧美激情视频 | 欧美亚洲在线 | 美女二区| 秋霞av一区二区三区 | 欧美黑人欧美精品刺激 | 亚洲午夜一区二区三区 | 91久久综合亚洲鲁鲁五月天 | 国产91丝袜在线18 | 久久伊人成人网 | 午夜a级片 | 午夜伦理福利视频 | 久久国产乱 | 视频国产在线 | 三级在线免费 | 麻豆影视大全 | 日日日网站 | 亚洲精品入口 | 国产女人18毛片水真多18精品 | 久久久国产片 | 动漫3d精品一区二区三区乱码 | 中文字幕在线免费视频 | 一区二区激情 | 在线播放少妇奶水过盛 | 人妻少妇精品无码专区久久 | 我不卡av| 中文字幕一区二区人妻 | 国产成人精品一区二区三区网站观看 | 国产欧美精品一区二区三区 | 日韩福利一区二区 | 精品三级在线观看 | 国产在线观看精品 | 婷婷色婷婷 | 超碰国产91 | 欧美呦呦 | 绿帽在线 | av中文字幕免费观看 | 无码久久av一区二区三区 | julia一区二区三区在线观看 | 五月婷婷av | 高潮喷水一区二区三区 | 国产日韩欧美二区 | 国产aⅴ激情无码久久久无码 | 激情文学亚洲色图 | 一本一道久久综合狠狠老精东影业 | 黄色片上床| 九色福利视频 | 日韩一级性 | 精品国产乱码一区二区三区99 | 在线你懂的 | 婷婷一级片 | xxx国产精品 | 国产成人亚洲综合a∨婷婷 台湾a级片 | 中国美女乱淫免费看视频 | 亚洲av成人片色在线观看高潮 | 曰批免费视频播放免费 | 日鲁鲁| 国产15页| 午夜精品福利一区二区三区蜜桃 | 女十八毛片 | 国产美女一级视频 | 欧美成人午夜电影 | 69看片| 一本色道久久hezyo无码 | 精品国产va久久久久久久 | 国产日韩一区二区在线观看 | 国产男男chinese网站 | 福利电影在线播放 | 天堂精品一区二区三区 | 久久久午夜视频 | 免费高清欧美大片在线观看 | 欧美日韩成人一区二区三区 | 亚洲情趣 | 麻豆成人精品国产免费 | 亚洲视频自拍 | 痴女扩张宫交脱垂重口小说 | 神马久久网站 | 在线只有精品 | 日本精品人妻无码免费大全 | v99av| 五月天国产视频 | 四虎影院免费 | 操色网 | 亚洲伊人久久综合 | 一级性生活毛片 | eeuss鲁片一区二区三区在线观看 | 一级黄色免费视频 | 污视频在线免费观看 | 美女亚洲一区 | 亚洲日本三级 | 四季av中文字幕一区 | 久久伊人av | 欧美人与禽性xxxxx杂性 | 91久久人人 | 在线激情网站 | 毛片无限看 | 成年人免费看的视频 | 国产乱国产乱老熟 |