Assembly, 這里把它翻譯為配件或程序集, 以示和組件(Component)加以區別。一個(gè)配件有時(shí)候是指一個(gè)EXE或者DLL文件, 實(shí)際上是一個(gè)應用程序(就是指帶有主程序入口點(diǎn)的模塊)或者一個(gè)庫文件。但是配件實(shí)際上可以是由一個(gè)或者多個(gè)文件組成(dlls, exes, html等等), 代表一組資源, 以及類(lèi)型的定義和實(shí)現的集合.。一個(gè)配件也可以包含對其它配件的引用。 所有這些資源、類(lèi)型和引用都在一個(gè)列表(manifest)中描述。manifest也是配件的一部分,所以配件是一個(gè)自我描述的,不需要其它附加的部件。
對其描述配件的另一個(gè)重要特性是,它是.Net環(huán)境下類(lèi)型標識的一部分,也可以說(shuō)是基本單位。因為,區分一個(gè)類(lèi)型的標識就是包含這個(gè)類(lèi)型的配件名字加上類(lèi)型名本身。
舉個(gè)例子,配件A定義了類(lèi)型T, 配件B也定義了同名類(lèi)型T,但是.Net把這兩個(gè)類(lèi)型認為是不同的類(lèi)型。 注意,不要把配件(assembly)和命名空間(namespace)混淆起來(lái)。其實(shí)命名空間僅僅是用來(lái)把類(lèi)型名用樹(shù)的形式組織起來(lái)的手段。對于運行是環(huán)境來(lái)講,類(lèi)型名就是類(lèi)型名,和名字空間一點(diǎn)關(guān)系都沒(méi)有。 總之,記住配件名加上類(lèi)型名唯一標識一個(gè)運行時(shí)類(lèi)型。 另外,配件也是.Net框架用于安全策略的基本單位,許多安全策略都是基于配件的。
怎樣生成一個(gè)配件呢?
生成一個(gè)配件的最簡(jiǎn)單辦法就是用.Net編譯器。例如:下面是一個(gè)C#程序ctest.cs
- public class CTest
- {
- public CTest()
- {
- System.Console.WriteLine( "Hello from CTest" );
- }
- }
命令行這樣寫(xiě):
csc /t:library ctest.cs
然后,你可以用ILDM查看一下這個(gè)配件中究竟定義了什么。
產(chǎn)生配件的另外一種辦法是,把多個(gè)模塊(modules, 它也是由編譯器產(chǎn)生的,對于C#,就是用/target:module選項,用配件連接器(al.exe)裝配成一個(gè)配件。
私有配件和共享配件之間有什么區別?
私有配件通常只被一個(gè)應用程序使用,一般它被保存在應用程序目錄,或者其子目錄下面.。而共享配件通常保存在全局的配件catch緩沖區中, 它是一個(gè)由.Net運行時(shí)環(huán)境維護的配件倉庫。
共享配件通常是許多程序都要使用的代碼庫,比如.Net框架的類(lèi)庫就是如此。
事實(shí)上, 我們應該如下區分三種配件:
* 私有(private):
只對一個(gè)應用程序可見(jiàn); 這是缺省配置, 其它的應用程序不能對其引用,這個(gè)配件必須在應用程序目錄或者其子目錄下面有個(gè)拷貝.
* 公有(public):
對其它的應用程序可見(jiàn), 不管它在什么目錄下面(可以是URL),其它的應用程序都可以對其直接引用.
* 公有共享(public shared):
共享的帶有版本控制的配件的當前實(shí)現, 應該使用這種類(lèi)型. 這種類(lèi)型特別適合于第三方控件.
Net環(huán)境怎樣查找配件?
當然是按照路徑查找, 規則如下:
* 在應用程序所在目錄及其子目錄下面私有配件
* 對于共享組件, 除了上面的規則, 再加上.Net提供的共享配件緩沖區路徑.
配件怎樣版本化?
我們已經(jīng)知道所有的類(lèi)型對象是使用全局的ID標識的, 那么配件是怎樣版本化呢?
配件通過(guò)版本號控制所謂的版本兼容性, 引用配件的時(shí)候,就需要給出配件名字和版本號.
版本號分為4個(gè)部分(舉例, 5.5.2.33). 分類(lèi)如下:
不兼容: 前兩個(gè)不同
可能兼容: 前兩個(gè)相同, 第3個(gè)不同
兼容: 前三個(gè)相同, 第4個(gè)不同
注意: 版本控制只適用于共享配件!
在傳統的Windows應用程序開(kāi)發(fā)中,動(dòng)態(tài)連接庫(DLL)為軟件提供了一種重要的可重用機制。同樣組件對象模型(COM)也通過(guò)DLLs和EXEs的形式提供了組件重用機制。在.NET的世界里, 則由assembly(譯者注:可以翻譯為程序集,不過(guò)感覺(jué)不十分貼切,因此以下均保留了英文原文)提供了類(lèi)似的可重用的代碼綁定機制。Assembly中包含了可以在CLR(Common Language Runtime)中執行的代碼。所有的.NET應用程序都是由一個(gè)或多個(gè)assembly組成的,不論你在創(chuàng )建一個(gè)Console, WinForms,WebForms應用程序或者一個(gè)類(lèi)庫時(shí),實(shí)際上你都是在創(chuàng )建assembly。甚至.NET本身也是通過(guò)assembly來(lái)實(shí)現其功能。
一個(gè)assembly可以由一個(gè)或者多個(gè)文件組成,簡(jiǎn)單來(lái)說(shuō),你可以把assembly理解成一個(gè)邏輯上的DLL。每個(gè)assembly必須有一個(gè)單獨的執行入口如DllMain, WinMain, Main等。Assembly也有一套配置(Deploying)和版本控制(Versioning)的機制。和傳統的DLL等COM組件相比,.NET有著(zhù)明顯的優(yōu)點(diǎn)(我們將在后面看到),另外它還可以避免一些諸如DLL兼容性等問(wèn)題的困擾(地獄般的困擾,譯者深有體會(huì )),并可以大大簡(jiǎn)化配置上存在的問(wèn)題。
通常我們可以用Visual Studio.NET或命令行編譯器(.NET SDK中帶的)來(lái)生成assembly。
如果你正確的編譯你的代碼,assembly就會(huì )以DLL或者EXE的形式保存在磁盤(pán)上。像這樣保存在物理磁盤(pán)上的assembly被稱(chēng)為靜態(tài)assembly。
.NET也允許你通過(guò)Reflection APIs來(lái)動(dòng)態(tài)生成assembly。(Reflection指獲得assembly信息以及assembly類(lèi)型信息的功能,類(lèi)型信息指assembly中的class, interface, member, method等內容。Reflection APIs在System.Reflection名稱(chēng)空間內)。像這樣的駐留在內存里的assembly被稱(chēng)作動(dòng)態(tài)assembly。如果需要,動(dòng)態(tài)assembly也可以保存在磁盤(pán)中。
下面我們將主要討論靜態(tài)assembly,本文所帶例程需要運行在裝有.NET SDK的機器上(Beta1或者Beta2)。你可以使用Visual Studio.NET來(lái)創(chuàng )建單文件的assembly。
當啟動(dòng)一個(gè).NET應用程序的時(shí)候,程序首先要檢查自己的安裝目錄中是否有需要的assembly,如果幾個(gè)程序運行,那么每個(gè)都要在自己的安裝目錄中查找自己需要的assembly。也就是說(shuō)每個(gè)程序都使用自己的assembly備份,這樣的assembly稱(chēng)為私有assembly。它們只在應用程序的安裝目錄范圍內有效。
一些情況下,你可以發(fā)現多個(gè)應用程序需要使用共享的assembly而不只是使用他們自己的,對這種情況,你可以在全局assembly緩存(譯者:Global Assembly Cache,這個(gè)翻譯有點(diǎn)不倫不類(lèi),大家明白就好)中管理該assembly(后面會(huì )提到)。這樣的assembly在全局過(guò)程中有效,可以被機器內的所有程序共享,被稱(chēng)為共享Assembly。如果應用程序不能在自己的安裝目錄中得到需要的assembly,它將在全局assembly緩存中查找。如果愿意你可以考慮把你的assembly成為共享assembly。
在深入assembly細節之前,我們先來(lái)大概了解一下和傳統的COM組件相比,assembly有那些優(yōu)點(diǎn):
Assembly可以把你從DLL地獄中解救出來(lái)。
DLL地獄很折磨人,典型的COM組件應用通常是把一個(gè)單獨版本的組件放在指定的機器上,這樣帶來(lái)的問(wèn)題就是開(kāi)發(fā)人員在更新或者維護組件時(shí)常常會(huì )因為組件版本的向后兼容性的限制而碰釘子。而.NET中解決這個(gè)問(wèn)題的方式很簡(jiǎn)單:建一個(gè)私有的assembly好了,它將有能力管理同一組件的不同版本,assembly保留其不同版本的copy,如果不同的應用程序需要使用同一組件的不同版本,那么通過(guò)調用組件不同的copy就可以。這樣就可以避免組件兼容性常常出現的問(wèn)題。.NET也允許我們跨機器來(lái)共享assembly,當然這種共享要受到嚴格的限制。
Assembly支持并行(side-by-side execution)執行
這么說(shuō)有點(diǎn)不好理解,不過(guò)很簡(jiǎn)單,也就是說(shuō)同一assembly的不同版本可以在同一個(gè)機器上同時(shí)執行。不同的應用程序
可以同時(shí)使用同一assembly的不同版本。共享式assembly支持這種并行執行。
Assembly是自描述的
COM組件需要把一些細節信息保存在系統注冊表或類(lèi)型庫里。當使用COM組件的程序運行時(shí),它首先要去注冊表里收集組件的細節信息然后才能調用。不象COM組件,.NET Assembly是自描述的,它們不需要把任何信息保存在注冊表里,所有的信息都存在于assembly自己的元數據(Metadata)里了(后面會(huì )講到Metadata)。
配置簡(jiǎn)化
assembly是自描述的,它不依賴(lài)于注冊表保存信息,因此完全可以使用XCOPY之類(lèi)的方法來(lái)配置它。
卸載容易
不需要注冊表,當然簡(jiǎn)單的刪掉就算是卸載了。
載創(chuàng )建一個(gè)assembly之前,我們先來(lái)了解一下assembly的組成結構。Assembly由以下幾部分組成:
Assembly Manifest(譯者:Assembly清單?不貼切,其實(shí)類(lèi)似于一個(gè)目錄或者入口)
包含assembly的數據結構的細節。
類(lèi)型元數據(Type Metadata)
包含assembly中允許的類(lèi)型數據。(前面提到過(guò),class, interface,member, property等)
Microsoft Intermediate Language code (MSIL)
單文件和多文件Assembly
上面提到的assembly結構中包含的東西可以被綁定到一個(gè)單獨的文件里。這樣的assembly叫單文件assembly。另外,所有的MSIL代碼和相關(guān)的元數據也可以被分到多個(gè)文件中,這些文件中每一個(gè)單獨的文件稱(chēng)為一個(gè).NET Module(模塊),.NET module中也可以包括其他一些文件如圖像文件或資源文件。
下面我們了解一下assembly manifest的更詳細的信息。Assembly manifest保存了assembly細節的數據結構。對多文件assembly來(lái)說(shuō),assembly manifest好像一個(gè)“綁定器”把多個(gè)文件綁定到一個(gè)assembly中。請注意Manifest和Metadata并不相同,Metadata保存的是在assembly和module里用到的數據類(lèi)型(如class, interface, method等)的相應信息,而Manifest是用來(lái)描述assembly本身結構的細節信息的。
對單文件Assembly來(lái)說(shuō),Manifest嵌在DLL或EXE文件內,對多文件assembly, Manifest可以?xún)惹对诿總€(gè)文件中也可以存在于一個(gè)委托(constituent)文件里。后面將會(huì )有詳細說(shuō)明。
下面列出了Manifest中的主要信息:
Metadata
Metadata數據是對assembly中數據的定義。每個(gè)EXE或DLL包含自己的詳細的類(lèi)型信息,這種數據叫Metadata。主要包括以下信息:
Modules
前面提過(guò)Assembly可以有一個(gè)或多個(gè)Modules組成。Module可以看作是一系列可管理的功能模塊。它們轉化為MSIL,一旦代碼在runtime中運行,它們就可以被加入assembly。請注意module本身并不能執行,要利用它們首先要把它們加到assembly里。當然一個(gè)module可以被加到多個(gè)assembly中;配置一個(gè)assembly的同時(shí)也必須配置所用的modules。
創(chuàng )建單文件Assemblies
現在我們了解了.NET Assembly的一些基本知識,下面我們可以用C#創(chuàng )建一個(gè)簡(jiǎn)單的assembly。你可以用VS.NET或者命令行編譯器,下面這個(gè)例子可以使用命令行編譯:
using System; public class Employee { string m_name; public string Name { get { return m_name; } set { m_name=value; } } public int GetSalary() { //put your logic instead of hard coded value return 10000; } }
上面的代碼說(shuō)明創(chuàng )建了一個(gè)叫Employee的類(lèi),該類(lèi)包含了一個(gè)的方法和一個(gè)屬性,你可以在文本編輯器中輸入以上代碼并保存為employee.cs。用下面的形式做命令行編譯:
csc /t:library employee.cs (csc是C Sharp Compiler)
執行過(guò)上面的命令,你將得到一個(gè)叫Employee.dll的文件,這就是一個(gè)單文件的assembly。
創(chuàng )建多文件的Assembly
這里我們將建立一個(gè)叫CompanyStaff的assembly,包括兩個(gè)類(lèi)Clerk和Manager。下面我們看看創(chuàng )建多文件assembly的兩種辦法:
第一種方法是分別編譯Clerk和Manager兩個(gè)類(lèi)到不同的modules中,然后把兩個(gè)modules加到CompanyStaff DLL中去得到最終的assembly。這時(shí)CompanyStaff DLL將管理assembly manifest。這種方法可以用正常的命令行編譯實(shí)現。(這里是CSC)
第二種方法是分別編譯Clerk和Manager兩個(gè)類(lèi)到不同的modules中,然后生成一個(gè)單獨的包含有assembly manifest的文件,并用這個(gè)文件來(lái)表示最終的assembly。這種方法將使用一個(gè)叫做AL.EXE的工具來(lái)創(chuàng )建assembly。
使用命令行編譯器創(chuàng )建多文件assembly
我們將進(jìn)行以下步驟:
Step1: 創(chuàng )建Clerk Module
把下面的代碼輸入到Clerk.cs中
- using System;
- public class Clerk
- {
- public string[] GetClerkNames()
- {
- string[] names={"Clerk1","Clerk2","Clerk3"};
- return names;
- }
- }
用命令行編譯這個(gè)類(lèi):
csc /t:module clerk.cs
這里/t:module開(kāi)關(guān)告訴編譯器把代碼編譯成一個(gè)module。
需要說(shuō)明的是,在beta1中編譯時(shí),如果使用C# compiler,將得到擴展名為.dll的module,如果用VB.NET的complier,得到的擴展名為.MCM。而在beta2種得到的都是擴展名為.NETMODULE的module.
Step2: 輸入下面代碼到Manager.cs文件
- using System;
- public class Manager
- {
- public string[] GetManagerNames()
- {
- string[] names={"Manager1","Manager2","Manager3"};
- return names;
- }
- }
用下面的命令行形式編譯:
csc /t:module manager.cs
Step3: 創(chuàng )建CompanyStaff assembly
在companystaff.cs文件中輸入以下代碼:
using System; public class CompanyStaff { public void DisplayStaff() { Clerk c=new Clerk(); Manager m=new Manager(); string[] ClerkNames; string[] ManagerNames; ClerkNames=c.GetClerkNames(); ManagerNames=m.GetManagerNames(); Console.WriteLine("Clerks :"); Console.WriteLine("======="); for(int i=0;i<ClerkNames.Length;i++) { Console.WriteLine(ClerkNames); } Console.WriteLine(); Console.WriteLine("Managers"); Console.WriteLine("======="); for(int i=0;i<ManagerNames.Length;i++) { Console.WriteLine(ManagerNames); } } }
用下面的命令行形式編譯:
csc /t:library /addmodule:clerk.dll /addmodule:manager.dll companystaff.cs
這里/addmodule開(kāi)關(guān)用來(lái)把前面建好的兩個(gè)module加到CompanyStaff.dll中,也就是一個(gè)多文件assembly中。
Step4: 創(chuàng )建一個(gè)客戶(hù)程序來(lái)使用assembly
在SimpleClient.cs文件中輸入以下代碼。
- using System;
- public class SimpleClient
- {
- public static void Main()
- {
- CompanyStaff cs =new CompanyStaff();
- cs.DisplayStaff();
- Console.Write("Press Enter To Exit...");
- Console.ReadLine();
- }
- }
用下面的命令行形式編譯:
csc simpleclient.cs /r:companystaff.dll
這樣就準備好了,你可以運行simpleclient.exe,將會(huì )列出clerk和manager的名字。
用AL工具創(chuàng )建一個(gè)多文件assembly
現在我們可以使用AL來(lái)創(chuàng )建CompanyStaff assembly了。AL是一個(gè)用來(lái)整合一個(gè)或多個(gè)MSIL代碼文件或者資源文件并生成一個(gè)帶有管理manifest assembly的工具。和前面例子中的Step1與Step2一樣生成modules。因為我們要在一個(gè)獨立的文件中建立assembly manifest,所以我們不必再親自創(chuàng )建CompanyStaff.dll文件,我們要用AL來(lái)生成它。
輸入下面的命令行:
al clerk.dll manager.dll /out:CompanyStaffAL.dll /t:library
AL命令需要接受MSIL文件或資源,以空格分開(kāi),另外我們還要指定輸出文件名(這里是CompanyStaffAL.dll,是為了與前面已經(jīng)生成的文件名區分開(kāi))
現在你的assembly準備好了,我們可以創(chuàng )建一個(gè)客戶(hù)程序來(lái)使用它。在前面的例子里,我們把DisplayStaff方法寫(xiě)在了CompanyStaff類(lèi)內,現在,我們可以通過(guò)AL得到CompanyStaff.dll,所以我們可以在客戶(hù)程序中寫(xiě)一個(gè)同樣的代碼來(lái)實(shí)現同樣的功能了。
在SimplaClientAL.cs文件中輸入下面代碼:
using System; public class SimpleClientAL { public void DisplayStaff() { Clerk c=new Clerk(); Manager m=new Manager(); string[] ClerkNames; string[] ManagerNames; ClerkNames=c.GetClerkNames(); ManagerNames=m.GetManagerNames(); Console.WriteLine("Clerks :"); Console.WriteLine("======="); for(int i=0;i<ClerkNames.Length;i++) { Console.WriteLine(ClerkNames); } Console.WriteLine(); Console.WriteLine("Managers :"); Console.WriteLine("======="); for(int i=0;i<ManagerNames.Length;i++) { Console.WriteLine(ManagerNames); } } public static void Main() { SimpleClientAL cs =new SimpleClientAL(); cs.DisplayStaff(); Console.Write("Press Enter To Exit..."); Console.ReadLine(); } }
編譯上面的代碼并運行,你可以得到和前面的例子一樣的結果。
共享式assembly和全局assembly緩存
到目前為止,我們看到的都是私有式的assembly。當然在.NET應用中,我們多數都在單獨的使用一些私有式的assembly,然而有時(shí)候你可能會(huì )需要在很多個(gè)應用程序中共享一個(gè)單獨的assembly的備份。我們前面提到過(guò),共享assembly需要把assembly放到全局assembly緩存中去(Global Assembly Cache)。全局assembly緩存是磁盤(pán)上一個(gè)特殊的目錄,一般它位于<driver>\WINNT\ASSEMBLY目錄下。注意當安裝過(guò).NET后,這個(gè)目錄在explorer下顯示和其他目錄有點(diǎn)不同,如果想看一下它的實(shí)際內容,你可以用命令行的形式來(lái)查看。
注意:不能簡(jiǎn)單的把你的assembly copy到這個(gè)目錄下。首先你需要給你的assembly一個(gè)strong name,然后可以用AL把這個(gè)assembly安裝到全局assembly緩存中去。
Strong Name
如果想把assembly設為共享,為了和其他共享的assembly區分開(kāi)來(lái),每一個(gè)assembly都需要一個(gè)唯一標志,這個(gè)標志指的就是Strong Name。 Strong Name是通過(guò)公鑰加密技術(shù)生成的。一個(gè)有私鑰的assembly可以生成和令一個(gè)帶有不同私鑰的assembly完全不同的strong name。.NET SDK使用一個(gè)叫SN.EXE(Shared Name)的工具來(lái)產(chǎn)生這樣的公鑰/私鑰對。
Versioning
向前面看到的那樣,多數時(shí)候,.NET assembly被用作私有模式。對這樣的assembly,因為它們都位于應用程序自己的目錄下,所以versioning看起來(lái)并不是十分重要。然而對共享式assembly來(lái)說(shuō),versioning是很重要的。共享式assembly可以以并行的形式使用(前面提到過(guò)并行使用的概念),因此完全有可能在同一臺機器上存在同一個(gè)assembly的不同版本。當應用程序要使用一個(gè)assembly時(shí)候,它就應該提供最近的或以前的版本的信息。如果開(kāi)發(fā)者需要使用不同版本,就需要在代碼中明確的設置版本號,其格式如下:
<major version>.<minor version>.<build number>.<revision>
Runtime將通過(guò)前兩個(gè)參數來(lái)決定當前使用的版本是否和以前的版本兼容(major version和minor version)。如果這兩個(gè)參數有變化,那么assembly將被認為是不兼容的,全局assembly緩存會(huì )為該assembly生成一個(gè)單獨的入口,如果在代碼中指定了版本號的話(huà),major version就是可選的了。
下面顯示了.NET如何將同一個(gè)assembly(EmployeeShared)的不同版本視為不同的assembly的例子。
創(chuàng )建一個(gè)共享式的assembly
現在你應該已經(jīng)知道什么是共享式assembly了,下面我們將創(chuàng )建一個(gè)叫EmployeeShared的assembly。創(chuàng )建一個(gè)共享式assembly包括以下幾個(gè)步驟:
Step1: 創(chuàng )建assembly代碼并在代碼中指定其版本號
在EmploeeShared.cs文件中輸入以下代碼:
using System; using System.Runtime.CompilerServices; [assembly:AssemblyVersionAttribute("1.1")] public class EmployeeShared { string m_name; public string Name { get { return m_name; } set { m_name=value; } } public int GetSalary() { //put your logic instead of hard coded value return 10000; } }
我們創(chuàng )建了這個(gè)類(lèi),包含一個(gè)屬性Name和一個(gè)方法GetSalary。注意AssemblyVersionAttribute的用法,它為該assembly設置了版本信息。
Step2: 用SN工具創(chuàng )建一個(gè)公鑰/私鑰對
為了給你的assembly賦一個(gè)Strong Name,你需要一個(gè)公鑰/私鑰對??梢允褂?NET SDK提供的工具SN (Shared Name),輸入以下命令行:
Sn -k employshared.snk
該命令在指定文件里創(chuàng )建了一個(gè)鑰匙對,參數-k表示我們要把鑰匙對寫(xiě)到輸出文件里。
擴展名.SNK只是個(gè)習慣,你可以讓它叫任何名字。
Step 3: 編譯assembly并用上一步中創(chuàng )建的公鑰/私鑰對簽名
現在我們可以用鑰匙對為我們的assembly簽名了,這可以通過(guò)在編譯時(shí)加上/a.keyfile開(kāi)關(guān)來(lái)實(shí)現:
csc /t:library employeeshared.cs /a.keyfile:employeeshared.snk
注意如果你在使用VS.NET,你可以更簡(jiǎn)單的在A(yíng)ssemblyInfo文件中指明key文件。如下所示:
[assembly:AssemblyKeyFile("employeeshared.snk")]
你也可以在這個(gè)文件里加上我們前面提過(guò)的般本號屬性而不用在源代碼里指定。
Step4: 在全局assembly緩存中安裝該assembly
我們的assembly已經(jīng)用過(guò)私鑰簽名了,下面可以把它放在全局assembly緩存中了。像前面一樣使用AL,命令行如下:
al /I:employeeshared.dll
開(kāi)關(guān)/I表示我們要將assembly安裝到全局assembly緩存中。
好了,現在assembly被安裝在全局assembly緩存并且可以使用了。想驗證一下的話(huà)到explorer中看一下Assembly目錄。
注意:在Beta2中,安裝assembly到全局assembly緩存中可以使用一個(gè)叫GACUTIL的工具??梢允褂肐LDASM.exe查看assembly信息。
有時(shí)候你可能需要分析assembly,尤其是別人開(kāi)發(fā)的assembly。這種情況下你可以使用一個(gè)叫ILDASM (Intermediate Language Disassembler)的工具。這個(gè)工具就象我們從前用過(guò)的OLE View或者VB的object viewer一樣,你可以把你的assembly或者module導入這個(gè)工具來(lái)查看assembly各方面的特性,比如它包含的member, method和manifest??雌饋?lái)就像下面這樣。
你可以通過(guò)雙擊樹(shù)結構中的節點(diǎn)得到更多的信息。
assembly是.NET的組成模塊。.NET應用程序由一個(gè)或者多個(gè)assembly組成。一個(gè).NET assembly由一個(gè)或多個(gè)文件組成并且在其自身的manifest中保存自己的注冊信息。通常一個(gè)assembly只為一個(gè)應用程序服務(wù),這樣的assembly叫做私有式assembly。你也可以通過(guò)配置讓一個(gè)assembly的copy為多個(gè)應用程序服務(wù)。這樣的assembly叫做共享式assembly。共享式assembly在全局assembly緩存中被管理。共享式assembly必須有一個(gè)在整個(gè)機器范圍內唯一標識的strong name。
聯(lián)系客服