How do I help my console application find all the referenced assemblies?

848 views Asked by At

tl;dr: My .NET Core 3.1 console application crashes with a FileNotFoundException because a (referenced?) assembly is present in version A, but required in version B. What to do?


I am trying to get a console application to run that is now built for .NET Core 3.1, but that used to be a .NET Framework 4.8 project before it was converted.

The console application crashes with a System.IO.FileNotFoundException, saying that the assembly Microsoft.Extensions.FileProviders.Physical in version 3.1.0.0 cannot befound. Now, I can confirm it's not there - in the directory where the .exe file of my console application resides, there is a file named Microsoft.Extensions.FileProviders.Physical.dll, but its assembly version is 3.1.6.0.

The console application and its dependencies are a part of a bigger project in said folder, with a total of over 1,200 DLLs.

In .NET Framework, I'd have used a binding redirect to use the present version 3.1.6.0 of the indicated assembly. In .NET Core, though, I understand these binding redirects are not a thing anymore. Thus, I'm not sure how to proceed, or how to even find out why the runtime thinks it needs to load Microsoft.Extensions.FileProviders.Physical.dll.

I may have found a partial solution that loads the version-mismatched assembly nonetheless (see observation (6) below), but then, I'm still getting a FileNotFoundException, this time for Microsoft.AspNetCore.Mvc.Abstractions.

Some observations and attempts to solve this:

  • (1) None of the > 1,200 .csproj files contains the string "Physical".

  • (2) More than 400 of the .deps.json files mention "Microsoft.Extensions.FileProviders.Physical.dll", all of them referring to version 3.1.0.0.

  • (3) All of the respective DLLs are loaded in an ASP.NET Core application where the version mismatch appears to cause no issues.

  • (4) The .deps.json file of my console application itself does not mention "Microsoft.Extensions.FileProviders.Physical.dll".

  • (5) Putting the right version of the file (3.1.0.0) into the directory where the .exe file resides and from where the .exe file is also executed does not change anything. The FileNotFoundException still occurs, still complaining about an absence of "Microsoft.Extensions.FileProviders.Physical.dll", version 3.1.0.0.

  • (6) Based upon the information on assembly resolution in .NET Core provided in a CodeProject article, I have attempted to force loading of the assemblies from the same directory myself (preliminary code, relying on the working directory):

    AssemblyLoadContext.Default.Resolving += (context, name) =>
    {
      var dllPath = System.IO.Path.Combine(Environment.CurrentDirectory, name.Name + ".dll");
    
      if (File.Exists(dllPath))
      {
        return AssemblyLoadContext.Default.LoadFromAssemblyPath(dllPath);
      }
    
      return null;
    };
    

    This appears to help to some extent! Now, the "Microsoft.Extensions.FileProviders.Physical.dll" assembly, and plenty (more than 250) of others, can be loaded. But this fails once "Microsoft.AspNetCore.Mvc.Abstractions", 3.1.0.0, needs to be loaded, which is not actually anywhere around the .exe file. Apparently, it must be loaded from somewhere else (?)

  • (7) While the above appears to provide a partial solution concerning the version mismatch, our entire source code contains no other occurrence of "AssemblyLoadContext". Therefore, the ASP.NET Core application apparently avoids the version mismatch issue using some other mechanism.

  • (8) Building my console application with build output set to Diagnostic1 confirms the suspected behaviour for the "Microsoft.Extensions.FileProviders.Physical.dll" file (shortened excerpt of the output):

    Dependency "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
      Could not resolve this reference. Could not locate the assembly "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
          For SearchPath "C:\(...)".
          Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.winmd", but it didn't exist.
          Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.dll",
              but its name "Microsoft.Extensions.FileProviders.Physical, Version=3.1.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
              didn't match the expected name "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
          Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.exe", but it didn't exist.
      Required by "(A)".
      Required by "(B)".
      Required by "(C)".
    

    In there, (A), (B), and (C) are assemblies of our own project. But as far as I can see, neither of their .csproj files mentions the text "Physical", so I do not understand why the DLL is allegedly being required by them.

  • (9) For the "Microsoft.AspNetCore.Mvc.Abstractions" assembly, diagnostic output says:

    Dependency "Microsoft.AspNetCore.Mvc.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
      Could not resolve this reference. Could not locate the assembly "Microsoft.AspNetCore.Mvc.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
          For SearchPath "C:\(...)".
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd", but it didn't exist.
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.dll", but it didn't exist.
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.exe", but it didn't exist.
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd", but it didn't exist.
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.dll", but it didn't exist.
          Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.exe", but it didn't exist.
      Required by "(B)".
    

    Once again, (B) is an assembly (same as the (B) in (8)) of our own, but looking into the .csproj file does not reveal a single occurrence of "Mvc.Abstractions".


I have found a couple of questions that appeared to provide solutions, but none of them worked for me:


How can I make the runtime load version of 3.1.6.0 of the indicated assembly rather than the requested version 3.1.0.0? Alternatively, how do I find out how the runtime does it when running the ASP.NET Core application?


1: in VS2019: Tools -> Options -> Projects and Solutions -> Build And Run -> MSBuild project build output verbosity -> Diagnostic

0

There are 0 answers