如何加载程序集并使用C#获取其中的所有类型(没有ReflectionTypeLoadException)

时间:2016-07-30 22:33:14

标签: c# exception reflection types .net-assembly

我正在尝试构建一个插件架构,其中dll包含在zip文件中,解压缩,存储,然后加载,以便可以构建和使用特定类型。从理论上讲,这听起来可行。但是我遇到了问题。我一直在

  

ReflectionTypeLoadException。

以下是我的工作:

        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);
            }                      
        }

当我在调试中逐步完成此操作时,异常发生在我正在运行assembly.GetTypes()的行上。

我在这里做错了什么?我应该使用新的AppDomain做什么吗?

更多信息:我装载的组件是一个测试组件。它确实提到了FakeItEasy。它有一个单独的类,这是我正在寻找的类。那个特定的类是另一个类的子类,它位于我的调用类引用的程序集中......这看起来令人困惑。让我用这种方式解释一下:

装配1:核心,装配2:Dummy_assembly,装配3:测试。

  • Tests和dummy_assembly都引用Core。
  • Dummy_assembly是我已压缩并尝试解压缩,加载然后搜索的dll。
  • 测试是我从中调用上面显示的方法的程序集。
  • 上面显示的代码位于Core。

我看过this。它似乎可能适用,但我不能完全告诉我(并且我不太明白为什么这个答案适用于那个问题)。

2 个答案:

答案 0 :(得分:0)

如果程序集包含一个无法加载的类型,它将抛出(通常是因为在一个无法解析的程序集引用上)......没有什么可以做的。

但是你可以捕获异常并检查Types属性并获取可以成功加载的类型。

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

如果您在另一个目录中引用了dll,您还可以处理AppDomain.AssemblyResolve事件并自行处理。

答案 1 :(得分:0)

在gettypes代码周围添加一个try / catch块。确保记录无法加载程序集的地方以进行调试。