Visual Studio adds unnecessary dll files in the output directory

424 Views Asked by At

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.

2

There are 2 best solutions below

8
Kebechet On

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)

0
Daniel Ribeiro On

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".