主机在自己的根目录中查找导出,因此在测试期间,我构建整个解决方案,并将Plugin.dll从Plugin类库bin / release文件夹复制到主机的调试目录,以便主机的DirectoryCatalog可以找到它,并且能够将其添加到CompositionContainer。每次重建后,Plugin.dll都不会自动复制,所以每次对合同/实施进行更改时,都会手动进行。
但是,我已经运行主机应用程序,而不是首先复制(更新的)Plugin.dll,并且在组合过程中引发了异常:
无法加载一个或多个请求的类型。获取更多信息的LoaderExceptions
这当然是因为它试图导入的Plugin.dll实现了不同版本的IPlugin,其中属性/方法签名不匹配。虽然在受控和受监控的环境中很容易避免这种情况,但通过简单地避免在插件文件夹中过时的IPlugin实现,我不能依赖于可能遇到传统插件的生产环境中的这些假设。
问题是这个异常有效地影响整个撰写操作,并且不导入导出。我宁愿不匹配的IPlugin实现被忽略,因此目录中的其他导出(实现正确版本的IPlugin)仍然被导入。
有办法完成这个吗?我正在考虑几个潜在的选择:
>在调用Compose之前或之后,在CompositionContainer上设置一个标志(“忽略失败的导入”)
>在< ImportMany()>上指定一个类似的标志。属性
>有一种方式来“钩住”到Compose()下的迭代过程,并能够单独处理每个(失败的)导入
>使用强名称签名以某种方式只寻找实现当前版本的IPlugin的导入
想法?
我也跑到了 a similar problem。如果您确定要忽略此类“坏”程序集,则解决方案是在创建每个程序集目录之后立即调用AssemblyCatalog.Parts.ToArray()。这将触发您提到的ReflectionTypeLoadException。然后,您有机会捕获异常并忽略错误的程序集。
当您为所有“好”程序集创建了AssemblyCatalog对象时,可以将它们聚合到AggregateCatalog中,并将其传递给CompositionContainer构造函数。