I believe I’ve exhausted the answers and comments on SO related to this topic. Full source code for the project I used to demonstrate the problem can be found here: https://github.com/jchristn/DependencyExample
Assume there is a solution with three projects. The first is a console app (Runner
) with dependency on RestWrapper v3.0.19. The second is a class library (Module1
) with dependency on RestWrapper v3.0.20. The third is a class library (Module2
) with dependency on RestWrapper v3.0.18.
All three of these attempt to perform an HTTP GET to a user-specified URL that is retrieved in Runner
. Runner
then uses AssemblyLoadContext
, LoadFromAssemblyPath
, Resolving
, and Activator.CreateInstance
to create and invoke the Process
method within Runner1
and then Runner2
, which perform the same HTTP GET, e.g.
Instantiating the modules
AssemblyLoadContext ctx1 = new AssemblyLoadContext("module1", false);
Assembly asm1 = ctx1.LoadFromAssemblyPath(Path.GetFullPath("module1/Module1.dll"));
ctx1.Resolving += (ctx, assemblyName) =>
{
Console.WriteLine("| Module 1 loading assembly " + assemblyName.FullName);
var parts = assemblyName.FullName.Split(',');
string name = parts[0];
var version = Version.Parse(parts[1].Split('=')[1]);
string filename = new FileInfo(Path.GetFullPath("module1/" + name + ".dll")).FullName;
Console.WriteLine("| Module 1 loading from file " + filename);
Assembly asm = Assembly.LoadFrom(filename);
Console.WriteLine("| Module 1 loaded assembly " + filename);
return asm;
};
Type type1 = asm1.GetType("Module1.Processor", true);
dynamic instance1 = Activator.CreateInstance(type1);
instance1.Process(url);
Simple RESTful Request
using (RestRequest req = new RestRequest(url))
{
using (RestResponse resp = req.Send())
{
Console.WriteLine("| Status (runner) : " + resp.StatusCode + " " + resp.ContentLength + " bytes");
}
}
I’ve operated under the assumption that by having these loaded in separate AssemblyLoadContext
s with their own Resolving
function that they would be able to load these differing versions, but it fails with an System.IO.FileLoadException: Could not load file or assembly 'RestWrapper, Version=3.0.20.0, Culture=neutral, PublicKeyToken=null'. Could not find or load a specific file. (0x80131621)
exception when attempting to run Runner1
.
Console Output
C:CodeMiscDependencyExampleRunnerbinDebugnet8.0>runner
URL: https://www.google.com
| Status (runner) : 200 57841 bytes
| Module 1 loading assembly RestWrapper, Version=3.0.20.0, Culture=neutral, PublicKeyToken=null
| Module 1 loading from file C:CodeMiscDependencyExampleRunnerbinDebugnet8.0module1RestWrapper.dll
System.IO.FileLoadException: Could not load file or assembly 'RestWrapper, Version=3.0.20.0, Culture=neutral, PublicKeyToken=null'. Could not find or load a specific file. (0x80131621)
File name: 'RestWrapper, Version=3.0.20.0, Culture=neutral, PublicKeyToken=null'
---> System.IO.FileLoadException: Could not load file or assembly 'RestWrapper, Version=3.0.20.0, Culture=neutral, PublicKeyToken=null'.
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at DependencyExample.Program.<>c.<Main>b__0_0(AssemblyLoadContext ctx, AssemblyName assemblyName) in C:CodeMiscDependencyExampleRunnerProgram.cs:line 49
at System.Runtime.Loader.AssemblyLoadContext.GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
at Module1.Processor.Process(String url)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
at DependencyExample.Program.Main(String[] args) in C:CodeMiscDependencyExampleRunnerProgram.cs:line 56
I’ve uploaded the full source (intentionally leaving out a .gitignore
) at the link above. The bin/Debug/net8.0
output of Module1
and Module2
are copied into subdirectory module1/
and module2/
in the Runner
‘s bin/Debug/net8.0
directory.
Also, another wrinkle to the problem, is that I need to run this on both Ubuntu and Windows.
Any help would be really appreciated!