How does .NET 4.7.2 manage redirects for a dependency compiled in .NET Standard 2.0?

2

Background

I have a large, old, monolithic application that currently targets .NET Framework 4.7.2 and uses several recently-written modules (also targeting net472) with no issues. There is also a recently-written module that targets .NET Standard 2.0, and it's giving me some problems.

All modules are loaded into the main application using Nuget packages.

The Issue

When attempting to call the principal method of the module (i.e., at runtime, in the deployed application), it errors out saying that it failed to find a particular version of System.Diagnostics.DiagnosticSource, despite that DLL existing in the appropriate \bin folder.

The dependency on System.Diagnostics.DiagnosticSource comes from Microsoft.EntityFrameworkCore.SqlServer, which has dependencies on it via both Microsoft.EntityFrameworkCore and System.Data.SqlClient.

I had suspected that the fact that an EntityFrameworkCore package is being called from a net472 application would have something to do with it (and it still may), but the existing net472 modules also use the Core package without errors. The exact same version, even!

Complicating Factors

  • The new module is only a class library, while the old modules are full-fledged WPF applications.
  • I can't upload new Nuget packages to our server, so with each change I make, I have to copy the DLLs from the module's \bin\Debug folder into the \bin folder at the application's install directory.

What Hasn't Worked

  • Installing the System.Diagnostics.DiagnosticSource Nuget package into the module. I have tried 4.0.3.0 (what the error message claims to be looking for), 4.5.0 (what the other modules expect), and 4.5.1 (what I think corresponds to the file version already in the install directory, see below).
  • Creating a net472 project in the module's solution to consume the netstandard2.0 project without Nuget, then redirecting the main app to use that project via a DLL reference.

What Has Worked

  • Creating a new folder in the install folder's \bin directory to contain only the new module's desired version of System.Diagnostics.DiagnosticSource.dll, namely file version 4.6.26515.6. The \bin folder already contains version 4.6.26919.2, but the module doesn't like that one.

This is a kludge, though. I shouldn't have to package two versions of the same DLL just because I have a Nuget package built on .NET Standard......should I?

Where do I go from here?

Additional Information

Here's the relevant fuslogvw entry. Note that it claims to be looking for version 4.0.3.0, despite MyApp.exe.config having a redirect specifying 0.0.0.0-4.5.1, and despite VS showing Microsoft.EntityFrameworkCore's dependency as System.Diagnostics.DiagnosticSource (4.5.0).

*** Assembly Binder Log Entry  (10/28/2019 @ 1:22:30 PM) ***

The operation failed.
Bind result: hr = 0x80131040. No description available.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\myApp\install\MyApp.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = System.Diagnostics.DiagnosticSource, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
(Fully-specified)
LOG: Appbase = file:///C:/myApp/install/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = MyApp.exe
Calling assembly : Microsoft.EntityFrameworkCore, Version=2.2.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\myApp\install\MyApp.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 4.0.3.0 redirected to 4.5.1.0.
LOG: Post-policy reference: System.Diagnostics.DiagnosticSource, Version=4.5.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/myApp/install/System.Diagnostics.DiagnosticSource.DLL.
LOG: Attempting download of new URL file:///C:/myApp/install/System.Diagnostics.DiagnosticSource/System.Diagnostics.DiagnosticSource.DLL.
LOG: Attempting download of new URL file:///C:/myApp/install/bin/System.Diagnostics.DiagnosticSource.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\myApp\install\bin\System.Diagnostics.DiagnosticSource.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: System.Diagnostics.DiagnosticSource, Version=4.0.3.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Run-from-source setup phase failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

Here is the entry from MyApp.exe.config:

<dependentAssembly>
    <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.5.1" newVersion="4.5.1" />
</dependentAssembly>
.net
nuget
dependency-management
.net-standard-2.0
asked on Stack Overflow Oct 28, 2019 by JAF • edited Oct 28, 2019 by JAF

1 Answer

0

It appears that the answer is "like any other redirects."

The fuslogvw dump showed the exact problem, and explains all the other errors I've been seeing. The DLL that I wanted to consolidate to (the one being used by all other modules, i.e., file version 4.6.26919.2) is not assembly version 4.5.1, but 4.0.3.1.

Correcting the binding redirect in myApp.exe.config resolved the problem.

answered on Stack Overflow Oct 28, 2019 by JAF • edited Oct 28, 2019 by JAF

User contributions licensed under CC BY-SA 3.0