2

I have a Visual Studio 2022 solution, with multiple projects, but four in particular are interesting here.

  • Provider1 which is based on .NET Framework 4.
  • Provider2 which is based on .NET 6.
  • Provider1Test which is based on .NET Framework 4.
  • Provider2Test which is based on .NET 6.

The Provider1 project has a number of classes, all in the Provider.Data namespace, one of them being Class1. This is my source code. The Provider1.csproj file:

<ItemGroup>
  <Compile Include="Class1.cs">
    <SubType>Code</SubType>
  </Compile>
  ...
</ItemGroup>

The Class1.cs file:

namespace Provider.Data
{
    public class Class1
    {
        ...
    }
}

The Provider2 project has links to these source files, i.e. "Add"->"Existing item"->"As link". It compiles with different conditional compilation symbols, so the output is not the same as for the Provider1 project. The Provider2.csproj file:

<ItemGroup>
  <Compile Include="..\Provider1\Class1.cs" Link="Class1.cs" />
</ItemGroup>

The Provider1Test project is an NUnit test project, that tests Provider1. It has multiple test classes, one of them is TestClass1.

The Provider2Test project is also a NUnit test project, with a ProjectReference to Provider2. It links to the test classes in Provider1Test in the same way as the source code does. The Provider2Test.csproj file:

<ItemGroup>
  <ProjectReference Include="..\Provider2\Provider2.csproj" />
</ItemGroup>
<ItemGroup>
  <Compile Include="..\Provider1Test\TestClass1.cs" Link="TestClass1.cs" />
</ItemGroup>

The TestClass1.cs file:

using Provider.Data;
namespace ProviderTests
{
    public class TestClass1
    {
        ...
    }
}

Now, this builds and runs just fine inside Visual Studio, but if I navigate to the Provider2Test folder and try to build with the dotnet build command, it doesn't find the source code.

C:\dev\DataProvider\Provider2Test>dotnet build
MSBuild version 17.3.1+2badb37d1 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  Provider2 -> C:\dev\DataProvider\Provider2\bin\x64\Debug\net6.0\Provider.Data.dll
      1 file(s) copied.
C:\dev\DataProvider\Provider1Test\TestClass1.cs(14,7): error CS0246: The type or namespace name 'Provider' could not be found (are you missing a using directive or an assembly reference?) [C:\dev\DataProvider\Provider2Test\Provider2Test.csproj]

Build FAILED.

What is the issue here, why doesn't dotnet build follow the reference path here, and how do I solve it?

I tried to create a TestClass2.cs file directly in Provider2Test, that is not a link but a standard compile include, and also using the Provider.Data namespace. It produces the same error.

Helena
  • 1,041
  • 2
  • 12
  • 24
  • This may help answer the question: https://stackoverflow.com/questions/48325953/dotnet-build-not-including-text-file-resource-content – sr28 Oct 06 '22 at 10:46
  • Check bin folder of project and make sure the dll is in the folder and the date is current. When a main project uses a child project the dll of the child project is copied to the bin folder of the main project. It is possible what is happening is you are building the Release version of the project and trying to copy the Debug version of the project. Or the debug version is older than release so it is missing some updates. – jdweng Oct 06 '22 at 10:56
  • @jdweng it... doesn't seem to be copied at all by the dotnet build command. In Visual Studio, when I build the Provider2Test project, it copies the Provider.Data.dll from Provider2, but when I run the dotnet build command on Provider2Test, nothing is copied. Copying it manually didn't help, though. – Helena Oct 06 '22 at 11:11
  • Delete (make a copy) the dll from original project and then build and see what happens. If dll doesn't get built than something is wrong with the csproj. Make sure you check all the bin folders for the file. The obj folder may not be updating. Deleting the bin should force everything to recompile. – jdweng Oct 06 '22 at 11:22
  • Okay, I found some kind of solution. If I, in Provider2Test, remove the ProjectReference to Provider2, and instead add an AssemplyReference to the ..\Provider2\bin\Debug\net6.0\Provider.Data.dll, it works! I don't like it though. – Helena Oct 06 '22 at 12:42
  • Additional information: If I change it back from an AssemblyReference to a ProjectReference the problem is reintroduced. So it seems that the ProjectReference is the problem. – Helena Oct 06 '22 at 14:10

1 Answers1

0

I found a workaround, so I'm posting it here and I'm going with it for now, but I don't think it's a good solution, and it doesn't explain the original issue, so I'm not going to mark this as the accepted answer.

In Provider2.csproj, I added that if it is built with dotnet build, it has a post-build target that copies its source code dll to Provider2Test. This is not run if the project is build within Visual Studio ("$(MSBuildRuntimeType)" == "Full").

  <Target Name="CopyDLLToTest" AfterTargets="Build" Condition="'$(MSBuildRuntimeType)' == 'Core'">
    <ItemGroup>
      <SourceDLL Include="$(TargetPath)" />
    </ItemGroup>
    <ItemGroup>
      <TestDirDestination Include="$(ProjectDir)..\Provider2Test\$(OutDir)" />
    </ItemGroup>
    <Message Text="Copying @(SourceDLL) to @(TestDirDestination)" Importance="high" />
    <Copy SourceFiles="@(SourceDLL)" DestinationFolder="@(TestDirDestination)" />
  </Target>

In Provider2Test.csproj I added a conditional assembly reference.

<ItemGroup>
  <Reference Include="Provider.Data" Condition="$(MSBuildRuntimeType) == 'Core'">
    <HintPath>$(OutDir)Provider.Data.dll</HintPath>
  </Reference>
</ItemGroup>

I kept the ProjectReference in all cases (both "Full" and "Core"), in order to trigger a Provider2 build whenever Provider2Test is built.

Helena
  • 1,041
  • 2
  • 12
  • 24