Skip to content

Migration to .NET 6 RC-2 from .NET 5 #22053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MartyIX opened this issue Oct 14, 2021 · 10 comments
Open

Migration to .NET 6 RC-2 from .NET 5 #22053

MartyIX opened this issue Oct 14, 2021 · 10 comments

Comments

@MartyIX
Copy link

MartyIX commented Oct 14, 2021

Hi,

I have attempted to migrate my C# solution (a set of projects) from .NET 5 to .NET 6 RC2 and I have also upgraded efcore to 6 RC2. However, now it happens that Microsoft.Extensions.DependencyInjection.Abstractions.dll is not copied to the bin\debug\net6.0 in a test project (the test project contains "exes references" (#1675))

I have asked around and @rolfbjarne adviced to use:

dotnet build /bl:msbuild.binlog # + install https://msbuildlog.com/

to compare builds on .NET 5 and .NET 6 to find out differences. I did that and I have found out that GenerateDepsFile task is in like each C# project mentioned in .NET 5 msbuild but that's not the case for .NET 6. This seems to be the difference. Is it possible that that's the reason why the Microsoft.Extensions.DependencyInjection.Abstractions.dll is not copied to the output of my test project?

Also I can see in project.deps.json (.NET 5):

"Microsoft.Extensions.DependencyInjection/5.0.2": {
  "dependencies": {
    "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0"
  },
  "runtime": {
    "lib/net5.0/Microsoft.Extensions.DependencyInjection.dll": {
      "assemblyVersion": "5.0.0.1",
      "fileVersion": "5.0.821.31504"
    }
  }
},

and in .NET 6, I can see

"Microsoft.Extensions.DependencyInjection/6.0.0-rc.2.21480.5": {

  "dependencies": {
    "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0-rc.2.21480.5",
    "System.Runtime.CompilerServices.Unsafe": "6.0.0-rc.2.21480.5"
  }
},

(i.e. no "runtime" here)

But still I don't really know why Microsoft.Extensions.DependencyInjection.Abstractions.dll is not copied to the output as a runtime library as my knowledge of msbuild is limited 😐

I have also tried to add <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0-rc.2.21480.5" /> to my testproject.csproj file but it does not force to add the missing .dll file to the output.

I understand that nobody can really tell me what exactly is wrong because they would need a repro project (which I don't have, the solution is not trivial and I'm not even sure if I can separate out that specific issue). However, maybe you guys can tell me if there was any change that might have the consequences I'm observing. Or possibly an idea how to debug it more or how to work it around.

Thank you!

Regards,
Martin

@ErikEJ
Copy link

ErikEJ commented Oct 14, 2021

How does this relate to EF Core?

@MartyIX
Copy link
Author

MartyIX commented Oct 14, 2021

EF Core depends on Microsoft.Extensions.DependencyInjection.Abstractions (AFAIK). And there might have been some change on your side (?).

I don't understand the issue well enough. So I'm asking somewhat blindly. I can open the issue in a different repo if you tell me which one sounds better.

Thanks

@dsplaisted dsplaisted transferred this issue from dotnet/efcore Oct 14, 2021
@ghost ghost added Area-NetSDK untriaged Request triage from a team member labels Oct 14, 2021
@dsplaisted
Copy link
Member

I've moved this to the sdk repo.

Is it possible for you to share the binlogs for us to investigate? They'll include lots of information (see https://aka.ms/binlog) including your project files and their imports, but not your C# source files.

@MartyIX
Copy link
Author

MartyIX commented Oct 15, 2021

Here is a simplified repro solution: Repro22053.zip

Scenario 1:

  1. <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.0-rc.2.21480.10" /> in SharedLibTests.csproj is NOT comment out.
  2. IntegrationTests/bin/Debug/net6.0 does not contain Microsoft.Extensions.DependencyInjection.Abstractions.dll.

Scenario 2:

  1. <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.0-rc.2.21480.10" /> in SharedLibTests.csproj IS commented out.
  2. IntegrationTests/bin/Debug/net6.0 contains Microsoft.Extensions.DependencyInjection.Abstractions.dll.

I don't really know why this happens.

Can anyone explain to me why this happens so that next time I know how to fix it?

@sfoslund
Copy link
Member

@MartyIX if the dll only shows up when the package reference you mentioned above is not commented out, then I expect it's copied as part of that package's dependencies. Is there any reason you expect it to be copied when the package reference is commented out?

@sfoslund sfoslund removed their assignment Oct 18, 2021
@sfoslund sfoslund removed the untriaged Request triage from a team member label Oct 18, 2021
@sfoslund sfoslund added this to the Discussion milestone Oct 18, 2021
@MartyIX
Copy link
Author

MartyIX commented Oct 19, 2021

@sfoslund

if the dll only shows up when the package reference you mentioned above is not commented out,

This sentence seems incorrect to me so let me rephrase it. What happens in Scenario 2 is that in case I have:

<!-- <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.0-rc.2.21480.10" /> --> in SharedLibTests.csproj.

then IntegrationTests/bin/Debug/net6.0 do constain Microsoft.Extensions.DependencyInjection.Abstractions.dll. So it's the other way around than what you said. I'm just making sure we understand each other.

And why it is important to have Microsoft.Extensions.DependencyInjection.Abstractions.dll in IntegrationTests/bin/Debug/net6.0? That's because IntegrationTests is a test project that is supposed to run Product.BoxProgram.exe as a process. So BoxProgram project should be deployed to IntegrationTests/bin/Debug/net6.0 in its entirety (with all dependencies) so that IntegrationTests/bin/Debug/net6.0/Product.BoxProgram.exe can be run.


Anyway, I have modified the repro to demonstrate the issue better here: Repro22053.zip. Please just compile, and run in a terminal Repro22053\IntegrationTests\bin\Debug\net6.0> .\Product.BoxProgram.exe, it should show you:

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
   at Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions options)
   at Microsoft.EntityFrameworkCore.DbContext..ctor()
   at WhalesSecret.SharedLib.Database.DatabaseContextBase..ctor() in C:\Repro22053\SharedLib\DatabaseContextBase.cs:line 18
   at Product.BoxProgram.Program.Main() in C:\Repro22053\BoxProgram\Class1.cs:line 14

and when you comment out <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.0-rc.2.21480.10" /> in SharedLibTests.csproj, recompile, the exception will be gone.

@dsplaisted
Copy link
Member

I took a look at this. What's going on is that the Microsoft.AspNetCore.Authentication.Negotiate package depends on the ASP.NET shared framework (Microsoft.AspNetCore.App). So when you reference it from the IntegrationTests project, the IntegrationTests project also depends on the shared framework.

There are some DLLs, including Microsoft.Extensions.DependencyInjection.Abstractions, that are available both as part of the ASP.NET Shared Framework as well as via NuGet packages. If a project uses the shared framework, then if those DLLs also come in via a NuGet package then they will not be included in the output, as they will be loaded from the shared framework.

So Microsoft.Extensions.DependencyInjection.Abstractions.dll isn't getting copied to the output folder of the IntegrationTests project because that API is part of the shared framework which the project references. However, the referenced BoxProgram exe doesn't depend on the shared framework, so it is not able to load the DLL.

If you can add the following to BoxProgram.csproj, that should fix the issue:

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

@MartyIX
Copy link
Author

MartyIX commented Oct 22, 2021

@dsplaisted Thank you! That's very informative explanation.

How did you actually find out all this? Did you read some msbuild scripts? I ask because I can debug C# code and given enough time I can find many bugs but msbuild is very hard for me to reason about. Is there any book or recommended resource to read to understand this stuff more in depth?

@dsplaisted
Copy link
Member

dsplaisted commented Oct 22, 2021

Here is the main thing you need to know to debug MSBuild: Create binary logs (with the -bl command line switch), and then use the MSBuild Log Viewer to view them. It will let you see all the property and item values, targets and tasks that run and their inputs and outputs, etc. You can search through everything, and you can double click on a project or a target to bring up the MSBuild source to see what it's doing.

For basic information about how MSBuild works, see the following:

Edit: This specific issue was easier for me to find because I'm quite familiar with how the .NET SDK works and have worked with or written a lot of the code. So I looked at a binlog of the build and searched for the DLL name that was missing, and when I saw that it was being counted as a conflict by the ResolvePackageFileConflicts task that pointed me in the right direction.

@MartyIX
Copy link
Author

MartyIX commented Oct 22, 2021

Thanks. I know MSBuild Log Viewer but it was still hard for me to find the difference (I found some differences but it was not easy). It's a great tool though. Anyway, this is extremely valuable answer for me. Thanks for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants