.NET 8 - FileNotFoundException when using reflection with 3rd party dll's

M74

New member
Joined
Jan 8, 2025
Messages
4
Programming Experience
10+
Hello.

I'm playing around with reflection and most of it works well.
At the moment I feel like "Pareto": 99% of the questions are answered in 1% of my time. For the last answer (1%) I'm now searching too long (99% :) ): To solve this, I need you! Thanks in advance

Let me explain:

In VS2022 I created a solution with the following projects:

1) PluginDLL1 (Class library): There is one class "DummyPlugin" with one method which returns "Hello from PluginDLL1".

2) PluginDLL2(Class library): There is one class "DummyPlugin" with one method. The method returns the concat of "Hello from PluginDLL2 + Hello from PluginDLL1". (In this project there is a project reference to the PluginDLL1. The second part is the return string from PluginDLL1...

3) TestConsole1: In this project there are project references to both class libraries. The calls of the method of both libraries are working fine.

Until now there is no problem!

4) TestConsole2_REFLECTION. With reflections I already tested the Assembly.LoadFrom() for both DLL and this works fine. But in my final application I will consume the DLLs from a database (binary data). (The database writing and reading of the file context works fine.)
With this I could successfully run the PluginDLL1 with the command Assembly.Load(<bytearrayFileContent>), because there is no reference to a third party DLL.
But, the same call with PluginDLL2 shows the following exception because of the missing DLL reference).

Exception DLL Missing.png


My question is how to add referenced libraries FROM MEMORY? Please note, I don't want to use the file system for this.

Thank you in advance for your answers!
 
Look into AssemblyLoadContext. You can use the AssemblyLoadContext.LoadFromStream method to load the plugin and AssemblyLoadContext.Resolving event to resolve the dependency.
 
Since these are 3rd party DLLs you will eventually be dealing with, beware of any copyright violations by inadvertently "distributing" the DLL.
 
Thank you very much, JohnH.
AssemblyLoadContext was the right answer!
And this is my C# snippet I'm testing with.

C#:
    // Load assemblies
    AssemblyLoadContext alc = new AssemblyLoadContext("TestAssemblyLoadContext", true);
    Assembly dll2 = alc.LoadFromStream(new MemoryStream(dll2ContentFromDB));
    Assembly dll1 = alc.LoadFromStream(new MemoryStream(dll1ContentFromDB));

    Type type = dll2.GetExportedTypes().First();
    if (type != null)
    {
      var c = Activator.CreateInstance(type);
      IDummyPluginInterface dummyPlugin = c as IDummyPluginInterface;
      if (dummyPlugin != null)
      {
        Console.WriteLine(dummyPlugin.HelloWorld());
      }
    }
    alc.Unload();

If someone has improvements, please let me know.
 
I would suggest:
C#:
var type = dll2.GetExportedTypes().FirstOrDefault(t => t.IsSubclassOf(typeof(IDummyPluginInterface)));
if (type != null)
{
    var dummyPlugin = (IDummyPluginInterface) Activator.CreateInstance();
    Console.WriteLine(dummyPlugin.HelloWorld());
}

The reasoning behind my suggestions are:
1) First() will throw an exception if it doesn't find anything.
2) What if the first type found is not a class that supports IDummyPluginInterface?
3) Using a try-catch as a substitute for branching logic is usually a poor idea.
4) We already know that what FirstOrDefault() can support the interface, so just cast the return directly and call it.
 
Skydiver,
thank you for the post and the modifications.

Is there a mistake in your code line?
C#:
var type = dll2.GetExportedTypes().FirstOrDefault(t => t.IsSubclassOf(typeof(IDummyPluginInterface)));
On debugging one step later the variable "type" is null. Now, there is not the result I expect...
(I'm not the very expert with lambda functions)
Do you have an idea?

Thanks in advance! BR
 
Likely a mistake somewhere there. I was typing that up in the gym.
 
Should be typeof(IDummyPluginInterface).IsAssignableFrom(t)
 
Back
Top Bottom