2014-09-03 68 views
1

我想確定哪些DLL我的程序集需要編譯。我在一個解決方案中有兩個示例項目,Scratch和ScratchTest。這裏是Scratch's Program.cs:C#隱藏的引用

using System.ServiceProcess; 

namespace Scratch 
{ 
    public class A : ServiceBase 
    { 
     static void Main(string[] args) 
     { 
     } 
    } 
} 

Scratch引用System.ServiceProcess.dll。

這裏是ScratchTest的Program.cs的:

namespace ScratchTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     Scratch.A o; 
     } 
    } 
} 

ScratchTest具有同時引用劃痕和System.ServiceProcess.dll。但是,由此產生的ScratchTest.dll沒有引用System.ServiceProcess.dll,只有Scratch。我知道這兩個通過看看

Assembly.GetReferencedAssemblies() 

並通過使用.net反射器。所以我的問題是,我怎麼知道ScratchTest需要System.ServiceProcess.dll來編譯?特別是考慮到SratchTest不一定要引用Scratch的所有參考資料,因爲可能會有一些衝突。謝謝,埃裏克

+0

這將是有用的知道你正在試圖用這些信息。另外,請記住直接依賴和間接依賴之間的區別。 ScratchTest直接依賴於Scratch。 ScratchTest對System.ServiceProcess.dll具有間接依賴性,因爲System.ServiceProcess.dll是Scratch的直接依賴。 – 2014-09-03 23:11:07

+1

我想要做的是有點難以解釋。我正試圖將一個項目從一個不同的構建系統轉換爲msbuild。因此我正在編寫.csproj文件。原始的構建系統不需要引用System.ServiceProcess.dll,因爲它默認包含在csc.rsp中。我使用的新構建系統強制使用flag/noconfig +,這意味着csc.rsp不會被包含在內,我必須明確指定引用,並且試圖檢測我需要的引用。 – 2014-09-03 23:29:32

+0

有趣。所以你有多個.Net項目,他們都依賴於csc.rsp進行依賴性檢測。現在您要爲每個項目創建一個項目文件,並在每個項目中包含正確的依賴關係。假設某些項目將依賴於其他項目是否正確?在這種情況下,您更願意將它們添加爲項目引用而不是dll參考? – 2014-09-04 00:15:20

回答

2

首先,您遇到的問題不是特定於ServiceBase類的。它與CLR如何檢測C#程序的類型依賴關係並加載引用的程序集有關。 C#編譯器只是在編譯時提前給你一個錯誤,因爲在CLR嘗試運行你的程序時,它在運行時也會失敗。下面是我在解釋您的問題的解決方案時所假設的:

ScratchTest是您的啓動項目,儘管您在解決方案中定義了兩個入口點,Main方法同時存在於「Scratch」和「ScratchTest」項目。爲了避免混淆,通常您應該只有一個主要方法(入口點)用於解決方案,儘管它不會影響當前的問題。

解決方案:當您在scratchTest項目中引用類A時,您不僅指的是類A,而且類ServiceBase也是因爲類「A」正在繼承它。所以當編譯器試圖編譯你的ScratchTest項目時,它試圖在當前引用的程序集中找到依賴類型,即「A」和ServiceBase。這裏重要的一點是,CLR總是試圖僅在其引用直接存在於您正試圖加載的程序集本身的清單元數據中的程序集(在本例中爲ScratchTest)中查找依賴類型。依賴類型從來不會像您構建解決方案那樣以遞歸方式進行搜索。基本上期望CLR能夠在所有引用的程序集中搜索依賴類型,反過來它們的引用程序集在你的.Net應用程序啓動時會對性能產生很大的影響。

同時核心.NET庫一樣MsCorLibSystemSystem.CoreSystem.Data通常在大多數創建C#項目的引用。然後考慮CLR實現了通過引用程序集遞歸查找依賴類型的邏輯,然後通過在每次搜索依賴類型時檢查它是否已經超過特定程序集來進行檢查這會進一步傷害啓動表現。

要解決你的代碼,你可以做以下兩件事情:

  • System.ServiceProcess.dll加入參考ScratchTest項目由C#編譯器的建議。

OR

  • 使用A類中的 「ScratchTest」 項目本身,因爲它已經包含了System.ServiceProcess.dll

〜乾杯

參考

RBT

+0

我最終不得不特殊處理掉這種情況下的dll,並將其包含到ScratchTest中。幸運的是,很少有與此相同的使用模式的dll。 – 2014-09-22 17:54:34

0

我不認爲你需要顯式調用測試文件的System.ServiceProcess。

測試文件沒有使用任何引用System.ServiceProcess中的任何方法或類,只是使用Scratch。

您不需要請求所引用的類使用的所有庫,只需要您的類正在使用的庫。

所以ScratchTest只使用Scrath而Scratch使用System.ServiceProcess。

+0

嘗試在VS中編譯(我使用2013)。如果ScratchTest沒有顯式引用System.ServiceProcess,它將不會編譯。 – 2014-09-03 23:24:37