(C#) Assembly.Load and references

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By WilfreGD

I am working on a project which requires a .dll library to be loaded dynamically. Basically, my Godot Project uses a .dll with some classes on it. But both this .dll and the Godot project need a whole other .dll on top of it so that they can share some core components.
Here is the context for what I have (it might sound a little complicated):

  • Assembly A: The core components
  • Assembly B: The library used by Godot
  • Assembly C: Godot itself

So… Godot and the Assembly B, both have a reference to the Assembly A (which is set on their .csproj) :

<Reference Include="AssemblyA">

Here is where things go wrong. In Godot, I dynamically load the Assembly B as I wish.

string path = @"..\AssemblyB.dll";
Assembly modAssembly = Assembly.LoadFrom(path);

Now, (as I’ve tested on a simple c# project before doing this in Godot) when loaded, Assembly B should get the reference to Assembly A through Godot since it has the reference itself. Yet it doesn’t. As if Godot didn’t load it while it actually is.

When I try to use my Assembly B, I simply get an error:

Could not load file or assembly 'AssemblyA'

I checked and made sure that the version is the same, and again, anywhere outside of Godot the loading works perfectly. It’s as if Godot didn’t give the references on Load.

Another thing I tried was to add the AssemblyA.dll next to the AssemblyB.dll so that Godot loads it at the same time, and… Yes, it is loaded… The only issue is that now there are two Assembly A being loaded and they are not the same, so I can’t check any equality on types because they are different.

What bothers me is that this is happening only in Godot and nowhere else. And I don’t get why this is the case.

And to give another example, here are the results of the dynamic loading when I was testing:

In a simple C# app:

Current Type: AssemblyA.Main
AssemblyB Type: AssemblyA.Main
Equals: True

In Godot with the exact same code:

Current Type: AssemblyA.Main
AssemblyB Type: AssemblyA.Main
Equals: False

Which shows that it was indeed loaded twice instead of being given by Godot, and both references are not the same for some reason I can’t explain. It seems like loading a .dll into Godot makes it part of it’s own domain with it’s own references, separate from Godot’s domain and references even though they are the same and should be shared.

Does Godot handle the loading differently than it should on simple C# apps?

I noticed a difference between loading a dll in the editor vs in a build.
In the editor, as I’ve said, dependencies needs to be copied around the .dll I want to load. But not in a build. Somehow, it is correctly loaded and given to the new Assembly. Yet it’s still not working.

After checking, the editor uses “dotnet/shared/Microsoft.NETCore.App/6.0.13/System.Private.CoreLib.dll” to execute the code, while the build uses “build/data_AssemblyGodot_x86_64/AssemblyGodot.dll” instead, this is the only difference there is.

And sadly, it still loads twice the dependencies and the equality between the types still returns false.

Godot Assembly: AssemblyA.Main
External dll: AssemblyA.Main
Equals: False

WilfreGD | 2023-02-01 11:10