Multiple DLLs from referenced .NET Standard projects
Asked Answered
S

3

6

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>
Supple answered 12/6, 2019 at 20:49 Comment(6)
wait... MainProject depends on TimeProject, and TimeProject depends on MainProject... did you typo? if not... that's a tricky buildClutter
Like Marc said, ordinarily, projects cannot depend on each other, as building one would require the other to be built, but you can't build the other until the first one is built... It's a nasty problem.Loewe
@MarcGravell Sorry that was a mistake. MainProject has no dependenciesSupple
What exactly is "my problem"? When debugging in Visual Studio, you will need all of the dependencies in the folder of ClockProject. When on a build server, it is fairly trivial to exclude unwanted DLLs when they are copied as artifacts. What is the scenario you are trying to solve for?Wen
@Wen But the attribute 'Copy Local = false' actually prevents dependencies from being copied in the output folder. This also works with directly referenced DLLs, but not with nested DLLs.Supple
@Supple - Do you understand How the Runtime Locates Assemblies and how difficult it is to override this behavior? If you expect the application to run after you have removed the DLLs it depends on from the path where the framework expects to find them, you might be in for a surprise to find out it doesn't work that way.Wen
S
5

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.

Supple answered 17/6, 2019 at 10:27 Comment(0)
H
2

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.

Hinterland answered 12/6, 2019 at 21:0 Comment(1)
I need a separate folder for each project and the circular reference fault in my question is editedSupple
P
1

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.

Pathfinder answered 16/6, 2019 at 5:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.