0

I'm trying to build a plugin architecture where dlls are included in a zip file, unzipped, stored, then loaded so that a specific type can be constructed and worked with. In theory, it sounds doable. But I'm having an issue with it. I keep getting a

ReflectionTypeLoadException.

Here's what I have that isn't working:

        var dlls = pluginFiles.Where(p => p.Value.FileInfo.Extension.ToLower() == ".dll").ToList();
        int num = 0;
        foreach(var dll in dlls){
            var assembly = Assembly.LoadFile (dll.Value.FileInfo.FullName);
            var pluginTypes = assembly.GetTypes().Where (p => p.IsSubclassOf (typeof (Plugin)));
            foreach(var pluginType in pluginTypes){
                var ctor = pluginType.GetConstructors ().FirstOrDefault ();
                if (ctor == null) continue;
                var plugin = (Plugin)ctor.Invoke (new object [] { });
                if (plugin == null) continue;
                num++;
                _mgr.RegisterNew (plugin);
            }                      
        }

As I'm stepping through this in debug, the exception happens on the line where I'm running assembly.GetTypes().

What am I doing wrong here? Should I be doing something with a new AppDomain?

Further info: The assembly I'm loading is a test assembly. It does have a reference to FakeItEasy. It has a single class, which is the class I'm looking for. That particular class is a subclass of another class that is in an assembly referenced by my calling class... That looked confusing. Let me explain it this way:

Assembly 1: Core, Assembly 2: Dummy_assembly, Assembly 3: Tests.

  • Both Tests and dummy_assembly reference Core.
  • Dummy_assembly is a dll that I've zipped up and am attempting to unzip, load, and then search.
  • Tests is the assembly from which I'm calling the method shown above.
  • The code shown above resides in Core.

I've looked at this. It seems like it might be applicable, but I can't fully tell how (and I don't quite understand why that answer works for that question).

Community
  • 1
  • 1
Jon Falkenstein
  • 135
  • 1
  • 9

2 Answers2

0

If the assembly includes a type that can't be loaded, it will throw (most often because on an unresolvable assembly reference)...nothing can be done about that.

But you can catch the exception and check the Types property and get the types that COULD be loaded successfully.

https://msdn.microsoft.com/en-us/library/system.reflection.reflectiontypeloadexception.types(v=vs.110).aspx

If you have referenced dlls in another directory you could also handle the AppDomain.AssemblyResolve event and handle it yourself.

Jeff
  • 35,755
  • 15
  • 108
  • 220
0

Add a try/catch block around the gettypes code. Make sure to log somewhere that you couldn't load the assembly for debugging purposes.

dvallejo
  • 1,033
  • 11
  • 25