将间接引用的程序集复制到输出目录 – 缺少程序集

可能重复:
Copy-local如何工作?

我有以下情况:

  • 有一个名为OLAF.Tools的项目,该项目引用C:\ Program Files \ SQLXML 4.0 \ bin \ Microsoft.Data.SqlXml.dll中的Microsoft.Data.SqlXml。 Reference Copy Local属性设置为True。 当我在bin目录中构建该项目时,我可以看到OLAF.Tools.dll和Microsoft.Data.SqlXml.dll
  • 有一个名为OLAF.Generator的控制台应用程序,该应用程序引用了OLAF.Tools(我使用Project选项卡添加了引用)。 当我在bin目录中构建该应用程序时,我只能看到OLAF.Generator.exe和OLAF.Tools.dll – 没有Microsoft.Data.SqlXml.dll,是什么让我感到满意。 另一个奇怪的事情是,即使该DLL丢失,应用程序也正常执行。

所以我的问题是:

  • 为什么Microsoft.Data.SqlXml.dll没有复制到OLAF.Generator控制台应用程序的bin文件夹?
  • 应用程序如何解析可以找到Microsoft.Data.SqlXml.dll的目录?

谢谢你,帕维尔

编辑1 :(在Marc Gravell的回应之后)

@Marc Gravell :你的回答让我深思熟虑,因为我可以发誓我总能在主应用程序的bin目录中看到间接依赖的程序集。 恕我直言,我不同意你的意见 – 尽所能尊重:)

当然,引用不是物理级联的(我们正在谈论与类,接口等的强关系) – 这正是我在构建OLAF.Tools库时想要实现的。 该库提供了一个抽象级别,它包含工厂,一个工厂接受作为参数字符串并返回接口。 该接口的一个特定实现使用Microsoft.Data.SqlXml组件。 因此,OLAF.Generator使用位于OLAF.Tools中的接口,但不知道Microsoft.Data.SqlXml中的组件。

除此之外(我想我们都知道我试图在前一段中解释的内容),在构建应用程序时,应复制依赖程序集(如果Copy Local设置为TRUE)。 我刚刚编写了示例应用程序,Project B lib引用了Project A lib,而Project C(控制台应用程序)引用了Project B.在Project C的bin目录中,我可以看到所有:Project A.dll,Project B.dll&Project C.exe。 因此,在讨论的场景中,Microsoft.Data.SqlXml不会在OLAF.Generator bin文件夹中结束的原因与该程序集本身有关。

编译器/ visual studio是否知道Microsoft.Data.SqlXml位于自动探测的目录中(或者它在GAC中),这就是为什么不复制该程序集的原因?

编辑2:我刚刚检查了GAC,事实上,Microsoft.Data.SqlXml.dll安装在GAC中。

Copy-local如何工作? log4net.dll没有被复制到MyProject输出目录 – 这是我的问题的答案。 当库安装在GAC中时,即使使用了COPY LOCAL设置,也不会复制它。

引用不会自动级联,因此添加对OLAF.Tools的引用也不会添加对SQLXML的引用。 如果要使用exe部署SQLXML,那么最方便的方法是 exe中显式添加对SQLXML的引用,并将其设置为copy local。 没有它,它就不会被部署。 基本上,开发人员有责任决定在运行时实际需要哪些文件(这通常是所使用的引用的子集,并且取决于只有您可以知道的许多部署决策)。

重新如何在运行时解决…探测路径有点像黑色艺术,主要是“app文件夹”,但它取决于配置,实际上可以咨询GAC。 您还可以通过AppDomain.Current.AssemblyResolve提供自己的解析器。