亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

[連載]《C#通訊(串口和網絡)框架的設計與實現》-9.插件引擎設計

2019-11-14 13:42:35
字體:
來源:轉載
供稿:網友

目       錄

第九章           插件引擎設計... 2

9.1           框架的契約-接口... 2

9.2           插件的雛形-抽象類... 3

9.3           實現接口... 4

9.4           反射機制... 5

9.5           反射工具類... 8

9.6           小結... 9

 

第九章     插件引擎設計

在介紹《第10章 宿主程序詳細設計》之前對接口和插件的相關內容進行一下整體介紹,在設計宿主程序的時候會用到這些知識,也是宿主程序與插件之間交互的核心內容。

9.1    框架的契約-接口

     插件式框架的宿主程序啟動后,它首先會加載相應的配置文件(例如:設備驅動配置文件等),找到相應的插件程序集,這些程序集以DLL文件格式存在,框架的宿主程序會找到指定的插件類型,由插件引擎依據插件類型(例如:IRunDevice)生成對象實例,由框架的宿主程序的管理器對插件實例進行管理和調度。

    一個插件程序集可能包括多個插件類型,那么框架宿主程序是如何識別這些類型是否為要加載的插件呢?每個插件對象都有一個身份標識-接口,這個標識在框架設計中被稱為“通訊契約”。接口可以被看作是一種定義了必要的方法、屬性和事件的集合,因此宿主程序就可以通過這種契約來生成具體的實例對象,并對其他組件或接口公開可操作的對象。

    插件式框架作為一個高聚合低耦合的平臺,它的功能定義與功能實現之間是分離的。只要符合插件規范的二次開發組件都可以掛載到框架平臺中,而它并不并心這些組件的具體功能。當然,框架平臺提供了一些必要的信息、機制來保證這些組件能夠正常實現二次開發的功能。

    在具有多個邏輯層次的結構設計中,各層之間的通信大多通過接口來實現,接口不會輕易改變,如果一個層的功能發生變化,不會影響其他層;只要正常實現了接口的組件功能,那么程序的運行就沒有問題。這種做法使得各層之間的相互影響降低到最低,總之,接口在多業務層級中能夠更好的解耦。

    在大部分功能性的編程和設計工作中,很少需要考慮“接口(interface) ”的情況,如果我們僅僅滿足通過控件的方式在IDE上編程和使用.NET Framework中一般的類庫,可能永遠不會在程序中使用到接口,即使在C#等面向對象語言的語法書中讀者會無數次看到過這個詞,也只是完成一般性的功能,并未掌握面向對象編程的核心思想。

     接口是一般行為的定義和契約。如貓和狗等動物,只需要將一般性的、公共性的屬性、動作等定義在接口里,例如:有眼睛、可以吃東西等。盡管不同動物之間存在很大差異,但是接口并不考慮它們各自的特性或功能的差異,例如:什么顏色的眼睛、吃什么東西等。它只關心這些類型都必須實現接口定義的所有功能,而實現了這個接口就可以被看作是一種動物。

    因此,接口的兩個主要的作用是:

n  定義多個類型都需要的公共方法、屬性。

n  作為一種不可實例化的類型存在。

繼承接口實現定義的方法、屬性等,實際上是實現了一種策略。

9.2    插件的雛形-抽象類

接口與抽象類非常相似,例如兩者都不能new一個實例對象,卻都可以作

為一種契約和定義被使用。但是接口和抽象類有本質的不同,這些不同包括:

n  接口沒有任何實現部分,但是抽象類可以繼承接口后部分實現代碼。

n  接口沒有字段,但是抽象類可以包含字段。

n  接口可以被結構(Struct)繼承,但是抽象類不行。

n  抽象類有構造函數和析構函數。

n  接口僅能繼承自接口,而抽象類可以繼承自其他類和接口。

n  接口支持多繼承,抽象類僅支持單根繼承。

在MSDN的相關內容中,給出了如下關于接口與抽象類的建議:

n  如果預計要創建組件的多個版本,則創建抽象類。抽象類提供簡單易行的方法來控制組件版本。通過更新基類,所有繼承類都隨更改自動更新。另一方面,接口一旦創建就不能更改,如果要更新接口的版本,必須創建一個全新的接口。

n  如果創建的功能將在大范圍的全異對象間使用,則使用接口。抽象類應主要用于關系密切的對象,而接口最適合為不相關的類提供通用的功能。

n  如果要設計小而簡練的功能模塊,應該使用接口。如果要設計大的功能單元,則應該使用抽象類。

n  如果要在組件的所有實現間提供通用的已實現功能,應該使用抽象類。抽象類允許部分實現類,而接口不包含任何成員的實現。

9.3    實現接口

接口和抽象類都可以作為“通信契約”,為子類提供規范。下面定義一個接口和抽象類。

//定義一個接口public interface IMyInterface{       void Action(int type);       string Method(int para);}//定義一個抽象類public abstract class BaseAbstract:IMyInterface{       public abstract void Action(int type); //繼承此類抽象類時必須實現這個方法。       public string Method(int para)         //實現這個方法       {              return para.ToString();       }}

繼承接口的話,需要實現全部定義的方法或屬性,如下代碼:

public class MyClass1:IMyInterface{       public void Action(int type)       {              Console.WriteLine(type.ToString());       }             public string Method(int para)               {              return para.ToString();       }}

繼承抽象類的話,只需要實現抽象類沒有實現的方法或屬性,一般為抽象方法或屬性,如下代碼:

public class MyClass2:BaseAbstract{       public void Action(int type)   //繼承抽象類,只需要實現這個函數。       {              Console.WriteLine(type.ToString());       }}

9.4    反射機制

    有了設備驅動或插件,還不能掛載到框架平臺的宿主程序中。我們考慮的問題是:已經有了任意多個類型插件程序集,框架平臺如何從程序集中根據類型定義在內存中生成插件對象?

   回顧普通情況下程序引用其他程序集組件的過程。首先,需要使用“添加引用”對話框加載程序集。然后,通過using關鍵字引用命名空間。最后,在命令空間下找到相應的類,并new出來一個實例。這是一種靜態加載程序集的方式。

   在插件式應用框架中,這種方法并不適合。宿主程序在編譯時并不知道它將要處理哪些程序集,更沒有辦法靜態的將插件類型通過using關鍵字引入,這些都是在運行時才能獲得的信息。在這樣的情況下,也無法使用靜態方法和new關鍵字來生成一個類型實例。而是需要在運行時獲得相關信息動態加載程序集,這個過程被稱為反射。

   反射是動態發現類型信息的一種能力,它類似后期綁定,幫助開發人員在程序運行時利用程序集信息動態使用類型,這些信息在編譯時是未知的,反射還支持更高級的行為,如能在運行時動態創建新類型,并調用這些類型的方法等。

    JIT編譯器在將IL代碼編譯成本地代碼時,會查看IL代碼中引用了那些類型。在運行時,JIT編譯器利用程序集的TypeRef和AssemblyRef元數據表的記錄項來確定哪一個程序集定義了引用的類型。在 AssemblyRef元數據記錄項中記錄了程序集強名稱的各個部分—包括名稱,版本,公鑰標記和語言文化。這四個部分組成了一個字符串標識。JIT編譯 器嘗試將與這個標識匹配的程序集加載到當前的AppDomain中。如果程序集是弱命名的,標識中將只包含名稱。

   .NET Framework中,為了實現動態加載,需要熟悉Assembly、Type和Activator等工具類的方法。框架平臺主要使用了Assembly工具類,這個類中包括Load、LoadFrom和LoadFile。

1.      Assembly的Load方法

   在內部CLR使用Assembly的Load方法來加載這個程序集,這個方法與Win32的LoadLibray等價。在內部,Load導致CLR對程序集應用一個版本重定向策略。并在GAC中查找程序集,如果沒有找到,就去應用程序的基目錄,私有路徑目錄和codebase指定的位置查找。如果是一個弱命名程序集,Load不會向程序集應用重定向策略,也不會去GAC中查找程序集。如果找到將返回一個Assembly的引用,如果沒有找到則拋出FileNotFoundException異常。注意:Load方法如果已經加載一個相同標識的程序集只會簡單的返回這個程序集的引用,而不會去創建一個新的程序集。

大多數動態可擴展應用程序中,Assembly的Load方法是程序集加載到AppDomain的首選方式。這種方式需要指定程序集的標識字符串。對于弱命名程序集只用指定一個名字。

2.Assembly的LoadFrom方法

    當我們知道程序集的路徑的場合,可以使用LoadFrom方法,它允許傳入一個Path字符串,在內部,LoadFrom首先調用AssemblyName的靜態方法GetAssemblyName。這個方法打開指定的文件,通過AssemblyRef元數據表提取程序集的標識,然后關閉文件。隨后,LoadFrom在內部調用Assembly的Load方法查找程序集。到這里,他的行為和Load方法是一致的。唯一不同的是,如果按Load的方式沒有找到程序集,LoadFrom會加載Path路徑指定的程序集。另外,Path可以是URL。

3.Assembly的LoadFile方法

    這個方法初一看和LoadFrom方法很像。但LoadFile方法不會在內部調用Assembly的Load方法。它只會加載指定Path的程序集,并且這個方法可以從任意路徑加載程序集,同一程序集如果在不同的路徑下,它允許被多次加載,等于多個同名的程序集加載到了AppDomain中,這一點和上面的兩個方法完全不一樣。但是,LoadFile并不會加載程序集的依賴項,也就是不會加載程序集引用的其他程序集,這會導致運行時找不到其他參照DLL的異常。要解決這個問題,需要向AppDomain的AssemblyResolve事件登記,在回調方法中顯示加載引用的程序集。類似于這樣:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args){       if (args.Name != null)       {              return Assembly.LoadFrom(string.Format("{0}//plugin//{1}.dll", application.StartupPath, new AssemblyName(args.Name).Name));       }       return null;}

      特別注意:要測試LoadFile有沒有加載引用的DLL,切不可將DLL拷貝到應用程序的根目錄下測試,因為該目錄是CLR加載程序集的默認目錄,在這個目錄中如果存在引用的DLL,它會被加載,造成LoadFile會加載引用DLL的假象??梢栽诟夸浵滦陆ㄒ粋€子目錄如plugin,把引用的dll拷貝到這里面進行測試。

     反射機制也有它的缺點:安全性和性能方面。但是,框架平臺在啟動的時候、以及增加新設備驅動(插件)的時候需要使用反射,一旦加載到宿主程序中,與靜態引用程序集沒有本質區別,都是寄存在內存中。

9.5    反射工具類

插件式框架平臺使用反射掛載設備驅動,在宿主程序中運行,需要一個專用的工具類來完成相關功能。代碼定義如下:

/// <summary>/// 一個輕便的 IObjectBuilder 實現/// </summary>public class TypeCreator : IObjectBuilder{       public T BuildUp<T>() where T : new()       {              return Activator.CreateInstance<T>();       }       public T BuildUp<T>(string typeName)       {              return (T)Activator.CreateInstance(Type.GetType(typeName));       }       public T BuildUp<T>(object[] args)       {              object result = Activator.CreateInstance(typeof(T),args);              return (T)result;       }       /// <summary>       /// 框架平臺主要使用了這個函數。       /// </summary>       /// <typeparam name="T"></typeparam>       /// <param name="assemblyname"></param>       /// <param name="instancename"></param>       /// <returns></returns>       public T BuildUp<T>(string assemblyname, string instancename)       {              if (!System.IO.File.Exists(assemblyname))              {                     throw new FileNotFoundException(assemblyname + " 不存在");              }              System.Reflection.Assembly assmble = System.Reflection.Assembly.LoadFrom (assemblyname);              object tmpobj = assmble.CreateInstance(instancename);              return (T)tmpobj;       }       public T BuildUp<T>(string typeName, object[] args)       {              object result = Activator.CreateInstance(Type.GetType(typeName), args);              return (T)result;       }}

9.6    小結

    下一章節介紹宿主程序詳細設計,需要對反射機制有一定的了解,并且會使用到上面的工具類,并在此基礎上進行擴展。

    框架平臺就要完全了,只需要一小步了。

 

作者:唯笑志在

Email:504547114@QQ.com

QQ:504547114

.NET開發技術聯盟:54256083

文檔下載:http://pan.baidu.com/s/1pJ7lZWf

官方網址:http://www.bmpj.net


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
高清欧美性猛交| 98精品国产自产在线观看| 亚洲欧美精品中文字幕在线| 色天天综合狠狠色| 2019中文字幕免费视频| 欧美夜福利tv在线| 久久99久久久久久久噜噜| 97香蕉久久夜色精品国产| 日韩精品亚洲视频| 日韩av网站大全| 欧美日韩成人黄色| 91av视频在线观看| …久久精品99久久香蕉国产| 影音先锋日韩有码| 国产精品爱啪在线线免费观看| 欧美激情一级精品国产| 久久久噜噜噜久久久| 日韩国产激情在线| 亚洲欧美在线免费观看| 国内精品模特av私拍在线观看| 青青在线视频一区二区三区| 欧美亚洲免费电影| 亚洲片国产一区一级在线观看| 日韩av影片在线观看| 亚洲乱码国产乱码精品精天堂| 日韩av在线资源| 91成人福利在线| 欧美一区视频在线| 欧美夜福利tv在线| 色噜噜国产精品视频一区二区| 色777狠狠综合秋免鲁丝| 成人精品一区二区三区电影免费| 精品亚洲精品福利线在观看| 夜夜嗨av色综合久久久综合网| 国产一区二区三区在线播放免费观看| 欧美福利视频网站| 亚洲精品久久久久| 日韩av影视在线| 国产精品老牛影院在线观看| 亚洲精品久久久久久久久久久久久| 日韩av在线资源| 国产精品第10页| 亚洲国产精品网站| 91久久精品国产91久久性色| 成人午夜激情免费视频| 精品综合久久久久久97| 欧美激情一区二区三区久久久| 亚洲视频在线播放| 日本精品久久久| 欧美视频第一页| 亚洲国产高清福利视频| 久久亚洲私人国产精品va| 欧美成人一区二区三区电影| 欧洲成人在线观看| 亚洲女性裸体视频| 亚洲国产精品成人av| 国产日本欧美一区二区三区在线| 国产97色在线|日韩| 国产精品第10页| 性欧美xxxx交| 久久亚洲一区二区三区四区五区高| 欧美中文字幕视频| 日本国产高清不卡| 国产精品美女主播在线观看纯欲| 国产精品亚洲网站| 欧美限制级电影在线观看| 亚洲国产精品悠悠久久琪琪| 91精品久久久久久久久中文字幕| 欧美主播福利视频| 揄拍成人国产精品视频| 欧美日韩亚洲一区二区| 成人a级免费视频| 欧美视频在线免费看| 亚洲最大福利视频网站| 亚洲人在线视频| 亚洲女同性videos| 欧美激情中文网| 国产精品99久久久久久人| 欧美又大粗又爽又黄大片视频| 亚洲精品国产拍免费91在线| 国产亚洲精品美女久久久久| 日韩中文字幕网| 亚洲国产中文字幕久久网| 国产一区二区三区视频| 久热精品视频在线| 黑人极品videos精品欧美裸| 97不卡在线视频| 欧美视频国产精品| 国产va免费精品高清在线| 成人精品一区二区三区| 亚洲人成网站999久久久综合| 91久久久国产精品| 日韩电影在线观看免费| 精品久久久国产| 亚洲欧美国产一本综合首页| 91av在线视频观看| 性欧美在线看片a免费观看| 亚洲最大成人在线| 日韩精品欧美国产精品忘忧草| 欧美富婆性猛交| 成人黄色免费网站在线观看| 日韩亚洲在线观看| 欧美高清一级大片| 亚洲欧美日韩国产成人| 国产精品高精视频免费| 亚洲第一网站免费视频| 亚洲免费av片| 国产v综合ⅴ日韩v欧美大片| 欧美精品精品精品精品免费| 欧美电影在线免费观看网站| 日韩av综合网站| 精品久久中文字幕| 亚洲另类xxxx| 日韩第一页在线| 国产精品入口福利| 久久男人av资源网站| www.日韩系列| 欧美最顶级的aⅴ艳星| 亚洲成人在线网| 亚洲国产精品热久久| 国产91成人在在线播放| 91在线视频精品| 欧美成人免费全部| 亚洲第一综合天堂另类专| 日韩精品中文字幕有码专区| 亚洲大胆人体av| 国产成人激情视频| 红桃av永久久久| 欧美成人在线网站| 国产色婷婷国产综合在线理论片a| 91精品国产综合久久香蕉| 综合激情国产一区| 国产欧美一区二区三区视频| 欧美大片网站在线观看| 91久久精品日日躁夜夜躁国产| 亚洲人成电影网站色xx| 欧美日韩国产二区| 国产一区二区三区在线观看网站| 久久久久久久久久久久久久久久久久av| 91精品国产色综合久久不卡98口| 久久久97精品| 精品中文字幕久久久久久| 亚洲精品国产欧美| 国产精品极品美女在线观看免费| 亚洲系列中文字幕| 在线精品国产欧美| 亚洲电影免费观看高清完整版在线观看| 色在人av网站天堂精品| 国产欧美日韩91| 91伊人影院在线播放| 久久精品国产99国产精品澳门| 亚洲女人被黑人巨大进入al| 成人网在线视频| 欧美巨乳在线观看| 久久不射热爱视频精品| 亚洲成年人在线播放| 久久天天躁狠狠躁夜夜躁2014| 欧美福利视频在线| 日韩在线观看免费全集电视剧网站| 国产精品嫩草影院一区二区| 97久久精品在线| 国产精品午夜国产小视频| 亚洲激情视频在线观看| 国产精品久久久久久久久久尿|