2011-08-27 53 views
16

在解決方案構建過程中,VS(msbuild?)遵循哪些規則?在哪些情況下,它會將間接引用的組件複製到輸出文件夾中,而哪些不是?引用程序集複製的規則

回答

18

我剛剛進行了一些實驗,它看起來像是任何間接引用的程序集,它的代碼在另一個程序集中直接引用的類型將被複制。如果代碼中沒有任何東西,它就不會。這裏是我的示例場景:

  • MainProgram:具有直接引用DirectAssembly的控制檯應用程序。代碼位於主:

    var foo = new DirectAssembly.SampleClass(); 
    
  • DirectAssembly:類庫與直接引用IndirectAssembly。包含SampleClass

    public class SampleClass 
    { 
        // Comment out this line to change the behaviour... 
        IndirectAssembly.IndirectClass neverUsed = null; 
    
        public SampleClass() 
        { 
         object x = Activator.CreateInstance("IndirectAssembly", 
                  "IndirectAssembly.IndirectClass"); 
    
        } 
    } 
    
  • IndirectAssembly:包含一個公共類IndirectClass與公共參數構造函數

如上所述,它的工作原理是因爲IndirectAssembly被複制到MainProgram(主程序)的輸出文件夾。如果註釋掉SampleClass中指示的行,則IndirectAssembly將複製而不是(即使它仍是引用),並且代碼在執行時會失敗。

我並不是說這些都是所有規則,但他們至少一個開始......

+2

+1如果來自其他程序集的類型被直接引用,它們將被複制。我有時會明確引用類型,這些類型通常會動態加載,以便部署它們。 –

+0

但我們不應該這樣做! – binki

+0

@binki:我同意這很痛苦,並且在ASP.NET 5中的NuGet中,它會好很多。但至少知道需要什麼幫助... –

2

它應該複製所有的遞歸引用。例如:

enter image description here

--- --- EDIT

的規則(至少在VS2010)似乎是如下:

  • 間接參考被複制只有實際使用。
  • 無論如何,即使沒有實際使用,也會複製直接引用。

因此,如果您想確保部署反射所需的程序集,請從根項目中引用它。

不考慮反思,似乎只需在項目層次結構的每個級別添加最少的參考集即可。

+0

以及如果從B中刪除程序集C的用法(但保留參考)會怎樣?它不會複製程序集C.那麼如果通過反射使程序集C用法呢?它不會複製組件C – SiberianGuy

+0

@Idsa:是的 - 這正是我正在寫的東西。 –

+1

@Idsa關於反思的觀點是有效的。至於保持從B到C的「不必要的」引用,確實C不會被複制到'bin',但是也會有**沒有**運行時錯誤。 –

1

我的經驗是,它會將所有直接引用組件,遞歸 - 也就是說,任何直接在您的代碼中引用,以及這些引用的任何內容。

任何在編譯時未被引用的代碼都不會被引用。因此只有在運行時解決的引用纔會被複制。這是因爲,儘管你可能確切地知道它所指的是什麼,但這個人並沒有。無論是反射還是使用激活器來引用它(因爲在已經給出的兩個答案中),因爲在編譯時,無法確定對象的實際類型。

該項目的引用指明代碼引用應該得到解決,但僅此而已 - 我想證據是,他們西港島線不可複製 - 這是所有基於編譯時間編碼引用。

這是一個原因,爲什麼一些注射技術可以工作,參考的分辨率不必在編譯,甚至部署點之前完成。

5

沒有通過以前的答案解決,所引用的組件,即是否在GAC一個微妙。

考慮一個項目引用組件A,而這又取決於組件B和C.組裝體C恰好已經安裝到GAC通過一些「其它產物」。我發現Visual Studio 2013將A和B但不是C複製到輸出文件夾,因爲C已經在GAC中。如果我在未安裝「其他產品」的計算機上運行該應用程序,則會遇到運行時綁定失敗。

我也注意到,微軟在這方面的文件似乎是錯誤的,至少在VS2013。

Managing Project References狀態

如果您部署包含對在GAC中註冊的自定義組件的引用的應用程序,組件將不會與應用程序部署,無論CopyLocal設置。在早期版本的Visual Studio中,可以將CopyLocal屬性設置爲引用以確保已部署該程序集。現在,你必須手動將程序集添加到\ Bin文件夾

我與VS2013顯示測試的是,與上述相反,CopyLocal =真總是複製直接引用裝配到輸出文件夾,而不管無論是在GAC中。但是間接引用的程序集只有在不在GAC中時纔會被複制。

此行爲意味着,以確保間接引用的組件部署您的應用程序,你應該明確提到,將它們添加,與CopyLocal = TRUE(或手動複製它們)。請注意,如果程序集位於GAC中,默認情況下CopyLocal將設置爲False。