Sunday, July 29, 2018

Libera me from [DLL] Hell

First, some mood music...

I think I've finally worked out one bit of .net core behaviour that has been causing me otherwise inexplicable file load exceptions for dependency assemblies of ones I've written. It happens it places where my code is loaded by some other .net core process (MSBuild, pwsh, ...), when I update some of my dependency .nuget files, even when the dependency is both in the manifest and is published alongside mine. This impacts things like MSBuild tasks linking FSharp.Core for versions > 4.3.4 on a machine with dotnet-msbuild (VS 15.7.5) installed; or PowerShell Core 6.0.2 loading netstandard2.0 assemblies that directly or indirectly link against one that is netcoreapp2.1 (which brings in a higher version of System.Runtime).

My working hypothesis, to explain when things fail, is that if an earlier version of the same assembly has already been loaded by the system into which yours is being integrated, any requests for a more recent dependency version will be rejected; whereas requests for older versions are ignored and the (newer) currently loaded one substituted instead. On the up-side, this would mean that .net core just assumes forward compatibility of the "older" (or at least linking-against-older) code, so your clients can happily update their systems and your code will continue to work; the corresponding down-side is that if you, as a developer, try to keep dependencies up to date, at best this means that the minimum supported version of the environment is dragged up (if you link a Task against Microsoft.Build.Utilities.Core 15.7.179, then your users will need to have VS15.7.5 or later), and in some cases that the code will outright fail, as above, and the update will need to be backed out.

No comments :