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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍

發布時間:2023/12/18 C# 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一些關于C#反射的知識,估計也就最多達到使用API的程度,至于要深入了解,以現在的水平估計很難做到,所以下面此篇文章,以作為一個階段的總結。

對于反射的總結,我想從以下幾個方面展開,首先是反射程序集,模塊,類的成員以及成員的一些信息;接下來就是動態調用類的成員方法;第三個方面就動態產生程序集,模塊和類以及類的成員。好了,現在就讓我們從反射各種信息開始吧

在C#中,我們要使用反射,首先要搞清楚以下命名空間中幾個類的關系:

System.Reflection命名空間

(1)?? AppDomain:應用程序域,可以將其理解為一組程序集的邏輯容器

(2)?? Assembly:程序集類

(3)?? Module:模塊類

(4)?? Type:使用反射得到類型信息的最核心的類

他們之間是一種從屬關系,也就是說,一個AppDomain可以包含N個Assembly,一個Assembly可以包含N個Module,而一個Module可以包含N個Type.

AppDomain這個類我們等下再來講解。我們先關注Assembly個類

在程序中,如果我們要動態加載一個程序集怎么辦呢?有幾種方式可以使用,分別是Load、LoadFrom和LoadWithPartialName三個Assembly的靜態方法.

先來講解Assembly.Load方法,該方法會有多個重載版本,其中一個就是提供程序集的詳細信息,即程序集的標識,包括程序集的名稱,版本,區域信息,公有密鑰標記,全部都是以一個字符串的形式提供,例如:"MyAssembly,Version=1.0.0.0,culture=zh-CN,PublicKeyToken=47887f89771bc57f”.

那么,使用Assembly.Load加載程序集的順序是怎樣的呢?首先它會去全局程序集緩存查找,然后到應用程序的根目錄查找,最后會到應用程序的私有路徑查找。

當然,如果你使用的是弱命名程序集,也即只給出程序集的名稱,那么這個時候,CLR將不會在程序集上應用任何安全或者部署策略,而且Load也不會到全局緩存程序集中查找程序集。

測試加載弱命名程序集的例子如下:

(1)?? 新建一個控制臺應用程序的工程,同時勾選創建解決方案

(2)?? 在解決方案中新建一個類庫的項目,隨便寫一個類和一個方法

(3)?? 在控制臺項目中,首先不添加引用,直接在Main方法中添加如下代碼:

Assembly assembly = Assembly.Load("MyAssembly");

if (assembly != null)

{ Console.WriteLine("加載成功"); }

執行程序,會拋出異常,說找不到該程序集。什么原因呢?因為我們使用的是弱命名程序集,Load方法不會去全局程序集緩存中查找,而該應用程序目錄下又沒有該程序集,所以程序找不到。這個時候,我們把程序稍微改一下,不用添加代碼,只需添加對MyAssembly的引用,重新運行程序,加載成功了。

接下來,我們就要看看Load怎么加載強命名程序集了,這個步驟稍微有些復雜。還是剛才的項目,找到MyAssembly.dll程序集所在的目錄,一般在bin"Debug目錄下

(1)生成密鑰對文件?? sn –k MyAssemblyKey.keys

你也可以自己隨便起一個密鑰對文件名

(2)生成公鑰文件

sn –p MyAssemblyKey.keys MyAssemblyPublicKey.PublicKey

注:查看公鑰命令:sn –tp MyAssemblyPublicKey.PublicKey

(3)創建強命名程序集。

很簡單,只需要在聲明命名空間的那句代碼上加上如下特性:

[assembly:AssemblyKeyFileAttribute(@”D:"Test"MyAssemblyKey.keys”)]

(4)?? 編譯項目

(5)?? 將程序集添加到程序集全局緩存

gacutil –i MyAssembly.dll

這個時候,轉到加載程序集的項目中,將Load方法中的參數改為”程序集名,Version=版本,culture=區域信息,PublicKeyToken=公鑰“,然后再去掉對程序集的引用,我們會發現,程序運行成功。表明Load到全局緩存區查找到了該程序集。

使用Load方法加載程序集,特別是強命名程序集,能在程序集上應用安全和部署策略,推薦使用該方法動態加載程序集,至于LoadFrom和LoadWithPartialName。

首先我們還是來看看LoadFrom方法,這個方法的原理是這樣的:我們如果要使用它來動態加載程序集,必須告訴它程序集的路徑,也即在哪個目錄下面,CLR會去加載與你指定的路徑完全匹配的程序集。記住,當我們指定程序集路徑時,不能包括任何關于程序集強命名的信息,所以,CLR不會在我們指定的程序集文件上應用任何策略,而且也不會去任何其他的地方搜索程序集,簡言之,它就是指哪打哪,呵呵。

例如:你有個程序集在D:/Test/MyAssembly.dll,你要用Assembly.LoadFrom加載該程序集,代碼就如下:

Assembly assembly = Assembly.LoadFrom(@”D:/Test/MyAssembly.dll”);

對于,LoadWithParitalName方法,推薦大家最好不要使用它,因為程序無法確定最終要去加載哪個程序集的版本,所以我們這里只是簡單的介紹一下它的工作原理:你可以傳遞一個程序集標識給它,包括程序集名稱,至于其他信息是可選的(區域信息,公有密鑰等),該方法執行時,會首先檢查應用程序中配置文件的qualifyAssembly節點,如果存在,則把該部分名稱的程序集替換成完全的程序集標識,如果不存在,則使用程序集名稱先到應用程序根目錄下查找,然后是私有目錄,沒有找到的話,就到程序集全局緩存中查找。簡單過程如下:

?????? 應用程序根目錄 -> 應用程序私有目錄 -> 程序集全局緩存.

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的區別!

1,Assembly.Load()

這個方法通過程序集的長名稱(包括程序集名,版本信息,語言文化,公鑰標記)來加載程序集的,會加載此程序集引用的其他程序集,一般情況下都應該優先使用 這個方法,他的執行效率比LoadFrom要高很多,而且不會造成重復加載的問題(原因在第2點上說明)

使用這個方法的時候, CLR會應用一定的策略來查找程序集,實際上CLR按如下的順序來定位程序集:

⑴如果程序集有強名稱,在首先在全局程序集緩(GAC)中查找程序集。?????????

⑵如果程序集的強名稱沒有正確指定或GAC中找不到,那么通過配置文件中的<codebase>元素指定的URL來查找

⑶如果沒有指定強名稱或是在GAC中找不到,CLR會探測特定的文件夾:

假設你的應用程序目錄是C:/AppDir,<probing>元素中的privatePath指定了一個路徑Path1,你要定位的程序集是AssemblyName.dll則CLR將按照如下順序定位程序集

????????? C:/AppDir/AssemblyName.dll

????????? C:/AppDir/AssemblyName/AssemblyName.dll

????????? C:/AppDir/Path1/AssemblyName.dll

????????? C:/AppDir/Path1/AssemblyName/AssemblyName.dll

如果以上方法不能找到程序集,會發生編譯錯誤,如果是動態加載程序集,會在運行時拋出異常!

2,Assembly.LoadFrom()

這個方法從指定的路徑來加載程序集,實際上這個方法被調用的時候,CLR會打開這個文件,獲取其中的程序集版本,語言文化,公鑰標記等信息,把他們傳遞給 Load方法,接著,Load方法采用上面的策略來查找程序集。如果找到了程序集,會和LoadFrom方法中指定的路徑做比較,如果路徑相同,該程序集 會被認為是應用程序的一部分,如果路徑不同或Load方法沒有找到程序集,那該程序集只是被作為一個“數據文件”來加載,不會被認為是應用程序的一部分。 這就是在第1點中提到的Load方法比LoadFrom方法的執行效率高的原因。另外,由于可能把程序集作為“數據文件”來加載,所以使用 LoadFrom從不同路徑加載相同程序集的時候會導致重復加載。當然這個方法會加載此程序集引用的其他程序集。

3,Assembly.LoadFile()

這個方法是從指定的文件來加載程序集,和上面方法的不同之處是這個方法不會加載此程序集引用的其他程序集!

結論:一般大家應該優先選擇Load方法來加載程序集,如果遇到需要使用LoadFrom方法的時候,最好改變設計而用Load方法來代替!

另:Assembly.LoadFile 與 Assembly.LoadFrom的區別

1、Assembly.LoadFile只載入相應的dll文件,比如Assembly.LoadFile("abc.dll"),則載入abc.dll,假如abc.dll中引用了def.dll的話,def.dll并不會被載入。

Assembly.LoadFrom則不一樣,它會載入dll文件及其引用的其他dll,比如上面的例子,def.dll也會被載入。

2、用Assembly.LoadFrom載入一個Assembly時,會先檢查前面是否已經載入過相同名字的Assembly,比如abc.dll有兩個版本(版本1在目錄1下,版本2放在目錄2下),程序一開始時載入了版本1,當使用Assembly.LoadFrom("2//abc.dll")載入版本2時,不能載入,而是返回版本1。Assembly.LoadFile的話則不會做這樣的檢查,比如上面的例子換成Assembly.LoadFile的話,則能正確載入版本2。

LoadFile:加載指定路徑上的程序集文件的內容。LoadFrom: 根據程序集的文件名加載程序集文件的內容。

區別:

LoadFile 方法用來來加載和檢查具有相同標識但位于不同路徑中的程序集.但不會加載程序的依賴項。

LoadFrom 不能用于加載標識相同但路徑不同的程序集。

?

轉自:http://blog.csdn.net/guxiaoshi/article/details/5009604

轉載于:https://www.cnblogs.com/vic-zhang/p/3273526.html

總結

以上是生活随笔為你收集整理的C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。