2011-08-27 51 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。