英文:
Visual Studio adds unnecessary dll files in the output directory
问题
我正在使用Visual Studio 2022预览版。我有一个包含两个库项目的.NET 4.8解决方案,为了简单起见,让我们称其中一个为"First"(生成"First.dll"),另一个为"Second"(生成"Second.dll")。第一个项目包含一些需要引用第二个项目的函数,换句话说,调用"First.dll"中的一些成员需要引用"Second.dll"。
问题在于,当我在一个新的空项目中引用"First.dll"时,即使我没有调用那些需要引用"Second.dll"的函数,编译项目时"Second.dll"也总是复制到输出目录中,就好像我没有在新项目中引用"Second.dll"一样。
我的问题是:这种恼人的行为如何称呼?是否存在直接的方法来防止这些不必要的dll文件被复制到输出目录中?(直接的方法,而不是使用后构建事件来删除额外的文件)。
在现实世界中,我遇到的情况是,我的.NET解决方案包含大约40个不同的库项目(这是一组用于不同目的的库),当我在一个新的空项目中引用此解决方案生成的单个dll库文件时,当我编译项目时,输出目录会被其他dll文件以及.NET框架程序集和不需要的NuGet包的垃圾文件填满,这些文件在程序的运行中没有任何必要。
我在这个.NET解决方案上工作了很多年,我认为只有当我开始将一些.NET内置的程序集引用替换为NuGet包时,我才开始遇到这种恼人的行为。
在这个.NET解决方案中包含的所有dll文件的"复制本地"和"使用特定版本"属性都设置为False。项目引用也是如此。
英文:
I'm using Visual Studio 2022 preview. I have a .NET 4.8 solution that contains two library projects, to make it simple let's say one is named "First" (which generates "First.dll") and the other is named "Second" (which generates "Second.dll"). The first project contains some functions that requires a reference on the second project, or said with other words, calling some members from "First.dll" requires a reference to "Second.dll".
Well, the problem is that when I reference "First.dll" in a new empty project, "Second.dll" is always copied to the output directory when I compile the project, even when I DON'T call those functions from "First.dll" that requires a reference on "Second.dll"... as I didn't referenced "Second.dll" in the new project.
My question is: how it is called this annoying behavior?, and it exists a direct way to avoid these unnecessary dll files from being copied in the output directory? (something direct, not using post-build events to delete the additional files).
In the real-world what is happening to me is that my .NET solution contains about 40 different library projects (it is a set of libraries for different purposes), and when I reference a single dll library file generated by this solution in a new empty project, when I compile the project the output directory gets full of garbage with other dll files from my solution and additional dll files from .NET framework assemblies and from nuget packages that are not required in any way for the operation of the program.
I'm working in this .NET solution many years, and I think that I started to experience this annoying behavior only when I started to replace some .NET built-in assembly references for NuGet packages.
All the dll files that are referenced in the projects contained in this .NET solution has "Copy Local" and "Use Specific Version" properties set to False. And the project references too.
答案1
得分: 1
"The "First.dll" depends on "Second.dll".
So "Second.dll" will always be copied together with "First.dll".
If your new project references "First.dll", then "Second.dll" is also required, otherwise "First.dll" will not work. Visual Studio builds this "Dependency Tree" when compiling a project, because otherwise, the primary dependencies will not work.
Maybe you are expecting "Second.dll" will be "embedded" somehow inside First.dll... But that's not how it works. Any dependency dll will have to be available for the application too.
Another option is:
- Build "Second.dll"
- Register it in GAC.
- Reference "Second.dll" in the "First" project.
- Build "First.dll"
- Reference "First.dll" in your new project.
This way, only "First.dll" will be copied to your new project... But watch out! "Second.dll" is still required. You'll have to register it in GAC, otherwise the program will crash when it tries to use something from "First.dll"."
英文:
The "First.dll" depends of "Second.dll".
So "Second.dll" will always be copied together with "First.dll".
If your new project references "First.dll", then "Second.dll" is also required, otherwise "First.dll" will not work. Visual Studio builds this "Dependency Tree" when compiling a project, because otherwise, the primary dependencies will not work.
Maybe you are expecting "Second.dll" will be "embedded" somehow inside First.dll... But that's not how it works. Any dependency dll will have to be available for the application too.
Another option is:
- Build "Second.dll"
- Register it in GAC.
- Reference the "Second.dll" on the "First" project.
- Build "First.dll"
- Reference the "First.dll" on your new project.
This way, only the "First.dll" will be copied to your new project... But watch out! The Second.dll is still required. You'll have to register it in GAC, otherwise the program will crash when it tries to use something on the "First.dll".
答案2
得分: 0
对于包含 First.dll
和 Second.dll
的示例。
查看此线程,其中解释了为什么这些DLL即使您没有使用它们的任何功能也会出现在输出中。
当您不使用该库的任何功能时,只需移除NuGet或库的引用,它就不会出现在生成输出中。
如果您引用了一个引入了约40个其他库的库,那么要么您有紧密耦合的逻辑,要么是非常复杂的工作流程。
紧密耦合的示例:我有一个包含一些不错扩展方法的 WebCrawler.dll
,我用它来进行字符串操作... 但是这个 WebCrawler.dll
也会调用API和HTML解析,这需要其他NuGet包(许多第三方DLL)。
如果在我的新项目中我只需要那些与字符串一起工作的方法,那么创建一个单独的库(例如 StringManipulation.dll
),将此字符串功能放入其中。然后将此字符串dll引用到WebCrawler
和您的NewProject
。
之后,您的新项目将只引用 StringManipulation.dll
,生成输出将不包含由 WebCrawler.dll
引用的未使用的DLL。
我在这个.NET解决方案中工作了很多年,我认为只有当我开始替换一些.NET内置程序集引用为NuGet包时,我才开始经历这种让人讨厌的行为。
是的,这可能是原因。因为.NET方法已内置到您的主程序集中或者是.NET运行时的一部分,所以它们不需要其他DLL。另一方面,NuGet基本上是DLL形式的第三方库。
问题是:为什么这是个问题?为什么多个文件是个问题?
如果您想只有一个文件与他人共享使用,那么要么不使用第三方库,要么使用类似ILMerge这样的工具来进行伪静态链接,将您的库与主程序集进行后期构建合并(这可能会引起一些问题)。
英文:
To the example with First.dll
and Second.dll
.
Check this thread where is explained why those DLLs are in the output even though you didnt use any of their functions.
When you dont use any functions of that library then simply remove the nuget or reference to the library and it wont be in the buid output.
In case when you reference one such library that brings ~40 others you either have tightly-coupled logic or really complex workflow.
E.g. of tight coupling: I have WebCrawler.dll
containing some nice extension methods which I use for string manipulation...but this WebCrawler.dll
also do calls to API and HTML parsing what requires other nuget packages(many 3rd party DLLs).
In case in my new project I need just those methods which work with strings, then create separate library (e.g. StringManipulation.dll
) where you will put this string functionality. Then reference this string dll to both WebCrawler
and also your NewProject
.
And after this split your new project will reference just StringManipulation.dll
and the build output wont contain unused DLLs referenced by WebCrawler.dll
> I'm working in this .NET solution many years, and I think that I
> started to experience this annoying behavior only when I started to
> replace some .NET built-in assembly references for NuGet packages.
yes, this could be the case. Because .NET methods are built into your main assembly or are part of .NET runtime, so they dont need other DLLs. On the other hand Nugets are basically 3rd party libraries in form of DLLs.
The question is: Why is it a problem? Why multiple files are problem ?
In case you would like to have just 1 file which you share to others to use then either dont use 3rd party libraries or use something like ILMerge to basically do pseudo-static linking to post-build merge your libraries to main assembly. (this can cause some problems)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论