1

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.

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417

2 Answers2

1

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

Daniel Ribeiro
  • 498
  • 1
  • 4
  • 15
0

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)

Kebechet
  • 1,461
  • 15
  • 31
  • "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." - This is not the case. I'm experiencing the problem only for referencing one of the dlls (First.dll), I don't have "Second.dll" referenced in the project but it is copied anyway to the output directory. – ElektroStudios Jun 28 '23 at 21:23
  • "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." - This is neither the case. The dlls from Nuget packages has "Copy Local" and "Use Specific Version" properties set to false, and they are part of the .NET runtime (eg. System.Numerics.dll), but are copied to output directory anyway when are NOT used. – ElektroStudios Jun 28 '23 at 21:23
  • "The question is: Why is it a problem? Why multiple files are problem ?" - For the same reason that when a person asks you to tell him what hour it is, you don't also tell him the current temperature, or for the same reason that when you download a :NET program in a zip file, it doesn't include all the .NET framework dll files inside, because it's totally UNNECESSARY, and additional files takes up space for distribution. It is not rational to compile an executable and distribute it with dlls that are completely unused and unnecessary for the operation of said program. – ElektroStudios Jun 28 '23 at 21:23
  • "E.g. of tight coupling: ..." - In fact inside this .NET solution I have various library projects dedicated to extension methods, for example: "Extensions.System.Drawing.dll" which is a project that contains loads of extensions methods for the members of "System.Drawing" namespace, and only very few of those extension methods depends on other extensions from "Extensions.System.Numerics.dll" (for not duplicating code in the other), but "Extensions.System.Numerics.dll" is always copied to output directory only for referencing "Extensions.System.Drawing.dll" in a new empty project. – ElektroStudios Jun 28 '23 at 21:34
  • 1 - Even though your main.dll reference just `First.dll`, the `Seconds.dll` in the output is expected when `First.dll` reference it. Because it is basically dependency of dependency. – Kebechet Jun 28 '23 at 21:35
  • 4 - tigh coupling - I have already provided you thread with explanation of this why also dead-code and it's references are there, even though you use just part of it. Here it is again: https://stackoverflow.com/questions/10192076/will-the-compiler-only-compile-code-that-can-get-executed – Kebechet Jun 28 '23 at 21:38
  • I read it about the dead code, but I think you are not understanding that this problem never happened to me before with this .NET solution (before I started to install nuget packages and do other things just updating the work). And of course I am not clear about why this is happening to me now, but I think that it is not everything as you are saying, because before it did not happen to me when I also had assemblies from the same .NET solution with dependencies/assembly references which were not copied to the output directory. – ElektroStudios Jun 28 '23 at 21:41
  • I appreciate the time and the help provided, but I sincerely think something is missing about this specific problem, due to what I have explained in my previous comment. – ElektroStudios Jun 28 '23 at 21:50