我正在尝试构建一个插件架构,其中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:测试。
我看过this。它似乎可能适用,但我不能完全告诉我(并且我不太明白为什么这个答案适用于那个问题)。
答案 0 :(得分:0)
如果程序集包含一个无法加载的类型,它将抛出(通常是因为在一个无法解析的程序集引用上)......没有什么可以做的。
但是你可以捕获异常并检查Types属性并获取可以成功加载的类型。
如果您在另一个目录中引用了dll,您还可以处理AppDomain.AssemblyResolve事件并自行处理。
答案 1 :(得分:0)
在gettypes代码周围添加一个try / catch块。确保记录无法加载程序集的地方以进行调试。