Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple DLLs from referenced .NET Standard projects

I've created three .NET Standard class librariy C# projects with Visual Studio 2017 and default settings.

Projects:

  • MainProject
  • TimeProject
    • Dependencies -> MainProject
  • ClockProject
    • Dependencies -> TimeProject

Each of them must have its own output directory like:

<OutputPath>C:\Projects\DataControl\Build\MainProject</OutputPath>
<OutputPath>C:\Projects\DataControl\Build\TimeProject</OutputPath> 
<OutputPath>C:\Projects\DataControl\Build\ClockProject</OutputPath>

The project DLL files are placed the output directories but the problem is that the referenced project DLLs are also placed in the output directory (TimeProject.dll and MainProject.dll)

Output directories (Copy Local = true):

  • \Build\MainProject:
    • MainProject.dll
  • \Build\TimeProject
    • MainProject.dll
    • TimeProject.dll
  • \Build\ClockProject
    • MainProject.dll
    • TimeProject.dll
    • ClockProject.dll

If I changed the property Copy Local to false, the DLL from the directly referenced project disappears. Thats better, but the nested referenced DLL remains -> MainProject.dll in ClockProject.

Output directories (Copy Local = false):

  • \Build\MainProject:
    • MainProject.dll
  • \Build\TimeProject
    • TimeProject.dll
  • \Build\ClockProject
    • MainProject.dll
    • ClockProject.dll

I want to prevent that the ClockProject creates a MainProject.dll in its output directory because the MainProject.dll already exists in the output directory of the MainProject.

I've a huge project and under this circumstance I have a lot of the same DLLs in my project folders. During the start of my program, however, a logic also searches the subfolders for DLLs and then several DLLs of the same project are found, this leads to version conflicts. In general, I want to keep this logic, so I am looking for a solution that will only generate the project DLL, not the referenced ones.

Finally, my csproj file. The other two project files look similar.

ClockProject.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <OutputPath>C:\Projects\DataControl\Build\ClockProject</OutputPath>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\TimeProject\TimeProject.csproj">
      <Private>false</Private>
    </ProjectReference>
  </ItemGroup>

</Project>
like image 585
Stampy Avatar asked Jun 12 '19 20:06

Stampy


People also ask

Can a DLL contain another DLL?

You can certainly embed another DLL as a resource and extract and load it at runtime if that's what you need.


3 Answers

I found the following solution:

The ClockProject requires the MainProject and the TimeProject.

If I reference only the TimeProject in the ClockProject then it works (because the TimeProject references the MainProject), but the MainProject.dll is copied to the ClockProject Output folder, which I do not want.

However, if I reference BOTH projects in the ClockProject, the Main- and TimeProject and set both to CopyLocal = false, then only the ClockProject.dll will be copied into the Output folder of the ClockProject.

like image 197
Stampy Avatar answered Nov 03 '22 00:11

Stampy


For projects like this I go to each project properties and set a Common Output directory. That way all of the projects dump their builds into one directory.

Since that is not possible, in your references select the MainProject.dll reference, look at the properties and set Copy Local to False.

like image 30
Erik Avatar answered Nov 02 '22 23:11

Erik


You've designed it the wrong way around and that's why you're getting version conflicts.

You need to redesign the solution so project's have a dependency tree with the right hierarchy:

Main Project <- Time Project <- Clock Project

To fix your solution:

  • Delete all the references in all projects.
  • Build ClockProject by itself (or MainProject if that's the confusing way you want to go).
  • Open TimeProject, reference Clock Project and build TimeProject (or from TimeProject ref Main and build).
  • Open MainProject and reference TimeProject (or from ClockProject reference TimeProject).

At each step you may need to refactor things around. Referencing Main from every project is a big no-no. You reference small, modular, encapsulated libraries and build up the dependency tree for the MainProject in the solution.

like image 35
Jeremy Thompson Avatar answered Nov 02 '22 23:11

Jeremy Thompson