C
C#15mo ago
ParaLogia

❔ How to dynamically load a different version of an assembly in the NET Core shared framework

Hi, I'm trying to dynamically load an assembly from a file 'System.Threading.Channels.dll', in a NET 6 project. But it throws an exception when trying to load the file. Minimum reproducible example below. Sandbox.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
Program.cs:
using System;
using System.IO;
using System.Reflection;

var directory = @"C:\path\to\directory\containing\the\file";
var dllName = "System.Threading.Channels.dll";
var assemblyPath = Path.Combine(directory, dllName);
Assembly.LoadFrom(assemblyPath);
// System.IO.FileLoadException: 'Could not load file or assembly 'System.Threading.Channels, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.'
using System;
using System.IO;
using System.Reflection;

var directory = @"C:\path\to\directory\containing\the\file";
var dllName = "System.Threading.Channels.dll";
var assemblyPath = Path.Combine(directory, dllName);
Assembly.LoadFrom(assemblyPath);
// System.IO.FileLoadException: 'Could not load file or assembly 'System.Threading.Channels, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.'
The Assembly.LoadFrom call throws the FileLoadException in the comment above. Full stack trace:
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Program.<Main>$(String[] args) in C:\Users\me\source\repos\Sandbox\Sandbox\Program.cs:line 8
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Program.<Main>$(String[] args) in C:\Users\me\source\repos\Sandbox\Sandbox\Program.cs:line 8
DLL properties in screenshot below. For this example, I can fix it if I add aPackageReference to "System.Threading.Channels" Version="7.0.0"OR if I change the TargetFramework to net7.0. But neither of these options are possible in the actual codebase. I can explain more about the actual context if needed, but right now I'm just trying to understand why this happens.
2 Replies
ParaLogia
ParaLogia15mo ago
Update: I found out that System.Threading.Channels is part of the NET Core shared framework, so the issue is probably that the NET 6 project already had the 6.0.0 version loaded, unless I specified the 7.0.0 version via nuget. From my research, Assembly.LoadFrom uses the default AssemblyLoadContext, and each context is limited to loading one single version of a given assembly (name). So I'm considering two new approaches: 1. Using a custom AssemblyLoadContext 2. Using Assembly.LoadFile instead of Assembly.LoadFrom I'm not sure what the potential ramifications/pitfalls of these approaches are, so I'd appreciate if anyone can chime in with suggestions.
Accord
Accord15mo ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server