2009-11-19 15 views
4

.NET如何找到命名空間的dll我是using? 是的,我們確實在/參考文獻中提到了路徑:c:\ program files **,但是在構建&後部署以及軟件安裝在某些用戶的機器上之後。它可能不像我(開發人員)提到的那樣。我的意思是它可能是一些其他地方的權利?.NET如何找到我正在使用的命名空間的dll?

  1. 那麼,.NET如何找到它?
  2. .NET在運行時如何知道dll中的所有命名空間是什麼?
  3. 如果用戶具有相同的dll,但他將其重命名? .net無法加載它呢?

回答

6

如果您運行fuslogvw.exe(來自.NET SDK)並啓用將所有綁定記錄到磁盤,則可以看到各種探測步驟。您將能夠看到.NET CLR用來解析程序集引用的各種路徑。經驗法則是首先嚐試全局程序集緩存,然後檢查本地目錄以及一堆其他備用路徑。

+0

這聽起來很有趣,但是當我啓動「Windows SDK工具> Fusion日誌查看器」時,每個按鈕在該窗口上都被禁用。在設置對話框中,一切都被禁用。 – claws 2009-11-19 10:55:53

+0

如果您在啓用UAC的情況下使用Vista或Windows 7,則應該從提升的命令提示符運行它,因爲它需要管理權限才能更改融合日誌記錄設置。 – Josh 2009-11-19 14:35:50

+0

「經驗法則是首先嚐試全局程序集緩存,然後檢查本地目錄以及一堆其他備用路徑。」 說如果我已經安裝了「.NET MYSQL CONNECTOR」(使用MySql.Data)。在編譯時使用引用它會檢測到dll,但是它的路徑將會像c:\ programfiles \ mysql \ .net \ mysql.dll一樣,但在應用程序被構建並且其他人正在使用它之後。我的所有應用程序都知道它的這個mysql.dll,但在用戶機器上。網絡連接器可能安裝在d:\ apps \ somecrap \ mysql.dll中。那麼clr如何檢測? – claws 2009-11-19 21:53:15

3

集和命名空間的名稱解釋是不相關的概念。

通過包含它們的name編譯裝配參考其他裝配。

加載程序集時,通過搜索here所述的名稱來加載其引用。組件的最常見位置是機器的Global Assembly Cache,以及應用程序的基本目錄。

加載程序集及其所有引用(以及引用等的引用)後,運行時會從程序集中加載所需的類型。

例如,如果您使用的類型String

using System; 

... 
String x = "Hello World"; 

C#編譯器查找String,它解析爲mscorlib裝配System.String類型,代碼轉變爲類似於此:當執行該語句

[mscorlib]System.String x = "Hello World"; 

所以運行時知道這兩個類型System.String的全名和包含該類型的程序集的名稱。

+0

編譯的程序集也可以通過弱名稱引用其他程序集。 – 2009-11-19 01:09:26

5

從技術上講,DLL中沒有任何命名空間。

在CLR級別上,根本沒有名稱空間,只有完整的類名。 CLR類名可以由任意Unicode字符的任意長的序列組成 - 例如就CLR而言,@#$%將是一個非常好的類名。

現在,按照慣例(CLS,具體而言),類名被限制在特定的Unicode字符(字母數字和_,和一堆其他外來的Unicode類別 - 詳情參見規範)和點, dot用來表示名稱空間。這純粹是編譯器(和其他工具)之間的約定。

因此,無論什麼原因,只要程序集引用某種類型,它就會使用其完整的CLR名稱,如System.String。但還有更多 - 實際上,它使用了一個完全合格的名稱,其中也包含一個程序集。如果您看到ildasm輸出,則可以看到這些輸出 - 它們看起來像[mscorlib]System.String,因此運行時知道在哪裏看。

換句話說,CLR確實看到程序集mscorlib.dll的類爲System.String,程序集B.exe將該類引用爲[mscorlib]System.String。您的using語句不會在輸出DLL/EXE中自行生成任何代碼;它就在那裏,所以你不必一直寫System.String

這是編譯器的工作體現你的代碼說String,在using System;聲明的範圍,它引用mscorlib.dll,以[mscorlib]System.String項目。這一切都是在編譯時完成的。 CLR在運行時唯一能解決的問題是解決mscorlib以在磁盤上找到實際的mscorlib.dll(另一個答案解釋了這種情況到底發生了什麼)。

+0

它如何從System.String解析爲[mscorlib] System.String 它如何知道它在mscorlib程序集中? System.String是相當常見的類型。那麼一些自定義的第三方類型呢?編譯器如何知道該類所在的程序集? – claws 2009-11-19 11:01:20

+1

它會查看您正在編譯的項目引用的所有程序集(或者在命令行中使用'/ r:'指定)。如果你引用的兩個程序集都定義了一個名爲'System.String'的類,你將會得到一個編譯器錯誤(但是你可以在C#中使用'extern alias'解決歧義程序集的問題。 – 2009-11-19 18:48:44

+0

「CLR在運行時唯一要做的就是解決mscorlib在磁盤上查找實際的mscorlib.dll。」 ---說如果我已經安裝了「.NET MYSQL CONNECTOR」(使用MySql.Data)。在編譯時使用引用它會檢測到dll,但是它的路徑將會像c:\ programfiles \ mysql \ .net \ mysql.dll一樣,但在應用程序被構建並且其他人正在使用它之後。我的所有應用程序都知道它的這個mysql.dll,但在用戶機器上.net連接器可能安裝在d:\ apps \ somecrap \ mysql.dll中。那麼它如何檢測?這是我原來的問題,如果我不清楚。 – claws 2009-11-19 21:52:21