组装在构建之外被优化
Posted
技术标签:
【中文标题】组装在构建之外被优化【英文标题】:Assembly being optimized out of build 【发布时间】:2014-10-15 06:11:40 【问题描述】:我有一个完全充满了在另一个程序集中实现接口的类的程序集。例如:
Main Assembly (Reference to both assemblies)
Shared Assembly
-----IModule
Class Assembly (Reference to shared assembly)
-----unknownType : IModule
-----unknownType2 : IModule
Main 程序集没有直接引用 Class 程序集中的任何类型。我正在寻找这样的类型:
// Load all referenced assemblies:
Assembly.GetExecutingAssembly().GetReferencedAssemblies()
.Except(AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName()))
.Distinct()
.ToList()
.ForEach(act => Assembly.Load(act));
// Find all instances of IModule in loaded assemblies:
var modules = from asm in AppDomain.CurrentDomain.GetAssemblies()
from provider in asm.GetTypes()
where typeof(IModule).IsAssignableFrom(provider)
...instantiate type etc...
如果我在类程序集中只引用了任意类型,那么它会显示在 GetReferencedAssemblies 中,被加载并正确返回 - 但一旦我删除对该类型的引用,它就不会转移到构建目录或显示为导致加载失败的引用程序集。
有没有办法强制 VS 在输出目录中包含这个程序集?主应用程序不应该知道类程序集中的任何类型。
【问题讨论】:
我记得有一个类似的问题,我找到的唯一解决方案是向项目中引用的程序集添加一个虚拟调用... @KevinD:由于主程序集不应该知道类程序集中发生了什么,因此我实际上无法添加虚拟引用,除非我预先知道类程序集中的类型是专门为那个目的。问题是这里的例子过于简化,这样做会给设计增加不必要的复杂性和泥泞。 这是一个特定于解决方案的问题,还是您可以提供在任意上下文中重现它的步骤? 您可以在“实施”程序集上添加构建后操作,以将其手动复制到主程序集的 bin 文件夹中。出于类似的原因,我必须做一次类似的事情才能让MEF 正常工作。 我想你是想在运行时注入实现而不是在编译时引用它们?我们通过在给定目录中加载所有二进制文件并针对其所需接口注册实现来实现这一点。然后您的主程序集可以使用构建后步骤将所需的实现复制到 bin 目录中。 【参考方案1】:我想我明白了你的问题,但你能澄清一下你的问题吗?您是否希望将作为项目引用添加的程序集与您的应用程序一起复制到您的输出文件夹中?你是如何添加参考的?它是您在文件对话框中浏览到的 .dll 或 .exe,还是您从“添加引用”对话框中的列表中选择的 COM 或 GAC 程序集?
如果您浏览到它,并且它不在 GAC 目录中,那么这种优化是可以预期的。在解决方案资源管理器中选择您的引用,并确保属性窗口中的“复制本地”设置为 true。即使是这样,您也可以尝试切换此设置。您的 .vsproj 文件可能只需要重新构建以包含引用。
如果您尝试从存储在字符串中或在运行时选择的文件名中引用 .dll,那么 Visual Studio 将无法知道您的应用程序正在使用它,但仍将其复制到您的输出中目录。不过,如果您有 .dll 的路径,使用 File.Copy 执行此操作应该不会太难。
【讨论】:
显然对原帖发表评论的人对问题有更好的理解,并提供了更好的答案。我期待一个作为项目依赖项(参考)添加的程序集被复制到输出目录,即使没有直接使用代码。 Visual Studio 将看到没有直接使用类型,并且不会将引用的程序集复制到输出目录。问题是关于如何防止这种优化行为。 啊,谢谢你的澄清。你的问题中没有问号,所以我有点想知道你想要回答你的哪个陈述。您是否尝试过打开解决方案目录中的 .csproj 文件并检查那里的依赖关系?我在 VS 2008 中未包含图像和图标资源时遇到类似问题,然后解决方案是删除明确阻止读取引用的行,因此未读取 Copy Local 设置。出于好奇,您为什么只想动态引用程序集,而不是代码中的名称?以上是关于组装在构建之外被优化的主要内容,如果未能解决你的问题,请参考以下文章