Visual Studio中的引用項目和直接引用DLL文件


在VS中引用類庫時有多種方法,其中用的最多的就是在引用時選擇項目選項卡引用本解決方案下的類庫項目和選擇瀏覽選項卡直接引用類庫DLL文件,實際上這兩種引用方式略有不同,今天就為大家總結下。

 

C#本地項目(控制台,winform)

  • 引用類庫項目,這時對引用DLL類庫做出任何修改會立刻生效,不用保存和生成類庫。如果刪除類庫項目,則本項目中引用的DLL也被刪除。
  • 引用類庫DLL,這時對類庫的修改,需要先生成類庫項目,再生成本項目才會生效。 如果刪除或改變類庫DLL的目錄,則本項目中的引用會指向本項目bin\debug目錄下生成的DLL(但是前提是在刪除或改變類庫DLL的目錄后,不要立即重新生成本解決方案,因為重新生成解決方案和生成解決方案的原理不一樣,重新生成解決方案時VS會先清空本項目bin\debug目錄下原先生成的DLL類庫文件也就是先清空解決方案,再生成本解決方案,而這時本項目bin\debug目錄中已經沒有原先生成的DLL類庫文件了,生成解決方案時當然會報錯,你必須先生成解決方案或運行本項目,這時本項目中的引用才會指向本項目bin\debug目錄下原先生成的DLL類庫文件,並將這個新的引用信息保存到項目文件,這時你再重新生成解決方案VS就不會去刪除bin\debug目錄下原先生成的DLL類庫文件了,但是如果該DLL類庫又引用了其它類庫項目(即本項目和這些其它的類庫項目之間是間接引用關系,關於間接引用詳情請見后面的附加內容),那么這時對本項目重新生成解決方案,VS還是會去將bin\debug目錄下該DLL類庫文件引用的其它類庫項目的DLL文件給刪除掉,所以這時如果本項目引用的DLL類庫調用了這些其它類庫項目中的代碼可能會報錯,所以請不要輕易去刪除或改變項目中所引用DLL類庫文件的目錄)。但是如果還原該類庫DLL到原目錄,則本項目中的引用又會指向該類庫DLL。
  • 以上無論哪種方式都要將引用的DLL文件的屬性設置為復制到本地,否則運行本項目時會報錯。

 

ASP.NET Web應用程序

  • 引用類庫項目,這時對引用DLL類庫做出任何修改會立刻生效,不用保存和生成類庫。如果刪除類庫項目,則本項目中引用的DLL也被刪除。
  • 引用類庫DLL,這時對類庫的修改,需要先生成類庫項目,再生成本項目才會生效。 如果刪除或改變類庫DLL的目錄,則本項目中的引用會指向本項目bin目錄下生成的DLL(但是前提是在刪除或改變類庫DLL的目錄后,不要立即重新生成本解決方案,因為重新生成解決方案和生成解決方案的原理不一樣,重新生成解決方案時VS會先清空本項目bin目錄下原先生成的DLL類庫文件也就是先清空解決方案,再生成本解決方案,而這時本項目bin目錄中已經沒有原先生成的DLL類庫文件了,生成解決方案時當然會報錯,你必須先生成解決方案或運行本項目,這時本項目中的引用才會指向本項目bin目錄下原先生成的DLL類庫文件,並將這個新的引用信息保存到項目文件,這時你再重新生成解決方案VS就不會去刪除bin目錄下原先生成的DLL類庫文件了,但是如果該DLL類庫又引用了其它類庫項目(即本項目和這些其它的類庫項目之間是間接引用關系,關於間接引用詳情請見后面的附加內容),那么這時對本項目重新生成解決方案,VS還是會去將bin\debug目錄下該DLL類庫文件引用的其它類庫項目的DLL文件給刪除掉,所以這時如果本項目引用的DLL類庫調用了這些其它類庫項目中的代碼可能會報錯,所以請不要輕易去刪除或改變項目中所引用DLL類庫文件的目錄)。但是如果還原該類庫DLL到原目錄,則本項目中的引用又會指向該類庫DLL。
  • 以上無論哪種方式都要將引用的DLL文件的屬性設置為復制到本地,否則運行本項目時會報錯。

ASP.NET 網站

  • 引用類庫項目,這時對引用DLL類庫做出任何修改會立刻生效,不用保存和生成類庫。如果刪除類庫項目,則本項目中引用的DLL也被刪除。
  • 引用類庫DLL,這時對類庫的修改,需要先生成類庫項目,再生成本網站項目才會生效。 如果刪除或改變類庫DLL的目錄,本項目中的引用還是會指向原先DLL類庫文件的目錄(不過ASP.NET網站是通過refresh文件指向該DLL文件的地址),不會指向本項目Bin目錄下生成的DLL,但是在對本項目生成解決方案時,會產生一個警告指示找不到所引用DLL類庫項目的原始文件,如果還原該DLL類庫到原目錄,警告就會消失。此外對ASP.NET網站項目重新生成解決方案時,VS不會去刪除本項目Bin目錄下的任何文件,所以即便是刪除或改變本項目所引用DLL類庫文件的目錄,由於本項目的Bin目錄下的所有DLL文件都還在,因此本項目的所有代碼還是可以正確運行。
  • ASP.NET 網站引用的DLL文件都會復制到本網站的Bin目錄。

 

 

附加內容:這里順便談談類庫引用鏈中的直接引用和間接引用的一個小問題 首先來談談什么叫引用鏈,大家知道C#項目中的類庫還可以引用其它的類庫,那么假如現在有3個類庫:LibA、LibB、LibC,這三個類庫存在引用關系:LibA<-LibB<-LibC(其中A<-B表示類庫B引用類庫A生成的DLL文件),那么我們就說這三個類庫LibA<-LibB<-LibC是一條引用鏈(LibA是引用鏈的頭,LibC是引用鏈的末尾)。

  • 直接引用:直接引用表示兩個類庫在引用鏈中的位置是相鄰的,比如上面的LibA和LibB以及LibB和LibC。
  • 間接引用:間接引用表示兩個類庫在引用鏈中的位置是不相鄰的,比如上面的LibA和LibC。

 

在引用鏈的直接引用關系中,比如LibA<-LibB,我們都知道,類庫項目LibB在生成后會將類庫項目LibA生成的DLL文件,復制到LibB項目自己的bin/Debug目錄下,這沒有什么問題。在引用鏈的間接引用中,比如LibA<-LibB<-LibC中,我們知道生成該引用鏈中的三個類庫項目后,LibC的bin/Debug目錄下肯定有LibB.DLL,因為LibC和LibB是直接引用關系,LibB的bin/Debug目錄下肯定有LibA.DLL,因為LibB和LibA是直接引用關系。但是問題是LibC的bin/Debug目錄下是否也有和其存在間接引用關系的類庫項目LibA的DLL文件LibA.DLL?

 

經過多次試驗,我發現如果類庫項目LibB中使用了類庫項目LibA中的成員時(即LibB不僅引用了LibA的DLL文件,還使用了LibA的DLL文件,比如調用了LibA的方法,聲明了LibA中類的對象等,但切記只用using導入LibA中的命名空間不叫使用),那么在引用鏈LibA<-LibB<-LibC生成后,類庫項目LibC的bin/Debug目錄下會同時生成LibA.DLL和LibB.DLL。但是如果類庫項目LibB中沒有使用類庫項目LibA中的成員時(即LibB只引用了LibA,但是LibB中完全沒有使用LibA),類庫項目LibC的bin/Debug目錄下就只有LibB.DLL。

 

所以你會發現其實VS在生成引用鏈時很聰明,因為在生成LibA<-LibB<-LibC中的LibC時,VS會去查看與LibC存在直接引用關系的類庫項目LibB的生成目錄bin/Debug下有幾個DLL文件,那么在本例中由於LibA和LibB是直接引用關系,那么LibB的bin/Debug下肯定有兩個DLL文件LibA.DLL和LibB.DLL。那么這時VS就會去探查LibB.DLL中是否使用了LibA.DLL。如果使用了VS就會把LibA.DLL、LibB.DLL同時Copy到LibC的bin/Debug目錄下。如果沒有使用LibA.DLL,那么VS會認為LibA.DLL是多余的,只會把LibB.DLL Copy到LibC的bin/Debug目錄下。

 

但是上面這段話不是絕對的,因為我發現如果將引用鏈末端的類庫項目LibC換成Asp.net網站或Asp.net應用程序,其生成DLL文件的原理是不一樣的,說明.net的每種項目引用DLL文件時都有自己的一套生成規則,上面只討論了類庫項目的生成規則。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM