2014-09-03 79 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