MEF:“无法加载一个或多个所请求的类型。检索LoaderExceptions以获取更多信息“ [英] MEF: "Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information"

查看:506
本文介绍了MEF:“无法加载一个或多个所请求的类型。检索LoaderExceptions以获取更多信息“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:我使用托管可扩展性框架根据在单独的dll中定义的接口契约在运行时加载插件(导出)。在我的Visual Studio解决方案中,我有3个不同的项目:主机应用程序,一个类库(定义接口 - IPlugin)和另一个实现该接口的类库(导出 - MyPlugin.dll)。



主机在自己的根目录中查找导出,因此在测试期间,我构建整个解决方案,并将Plugin.dll从Plugin类库bin / release文件夹复制到主机的调试目录以便主机的DirectoryCatalog会找到它,并且可以将其添加到CompositionContainer。每次重建后,Plugin.dll都不会自动复制,所以每次对合同/实施进行更改时,我都会手动执行。



然而,几次我已经运行主机应用程序,而不是首先复制(更新的)Plugin.dll,并且在组合过程中引发了异常:



Unable加载一个或多个请求的类型。检索LoaderExceptions以了解更多信息



这当然是因为Plugin.dll尝试导入实现了一个 IPlugin的不同版本,其中属性/方法签名不匹配。虽然在受控和监控的环境中很容易避免这种情况,但通过简单地避免(duh)插件文件夹中过时的IPlugin实现,我不能依赖于可能遇到传统插件的生产环境中的这些假设。



问题是这个异常有效地扰乱了整个Compose操作,而不导入导出。我希望不匹配的IPlugin实现被忽略,所以目录中的其他导出(实现正确的IPlugin版本)仍然被导入。



有没有办法完成这个?我正在考虑几个潜在的选择:




  • 在CompositionContainer之前有一个标志设置(忽略失败的导入)或者当调用Compose

  • < ImportMany()> 属性
  • $上指定一个相似的标志b $ b
  • 有一种方法可以钩到Compose()下的迭代过程,并且能够单独处理每个(失败的)导入

  • 使用强名称签署到某种方式只寻找实现当前版本的IPlugin



想法?

解决方案

我也遇到了一个类似的问题



如果您确定要忽略这样的坏程序集,那么解决方案是调用 AssemblyCatalog.Parts.ToArray()。这将触发您提到的 ReflectionTypeLoadException 。然后,您有机会捕获异常并忽略错误的程序集。



当您创建了 AssemblyCatalog 对象所有的好程序集,你可以将它们聚合在一个 AggregateCatalog 中,并将它传递给 CompositionContainer 构造函数。 p>

Scenario: I am using Managed Extensibility Framework to load plugins (exports) at runtime based on an interface contract defined in a separate dll. In my Visual Studio solution, I have 3 different projects: The host application, a class library (defining the interface - "IPlugin") and another class library implementing the interface (the export - "MyPlugin.dll").

The host looks for exports in its own root directory, so during testing, I build the whole solution and copy Plugin.dll from the Plugin class library bin/release folder to the host's debug directory so that the host's DirectoryCatalog will find it and be able to add it to the CompositionContainer. Plugin.dll is not automatically copied after each rebuild, so I do that manually each time I've made changes to the contract/implementation.

However, a couple of times I've run the host application without having copied (an updated) Plugin.dll first, and it has thrown an exception during composition:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information

This is of course due to the fact that the Plugin.dll it's trying to import from implements a different version of IPlugin, where the property/method signatures don't match. Although it's easy to avoid this in a controlled and monitored environment, by simply avoiding (duh) obsolete IPlugin implementations in the plugin folder, I cannot rely on such assumptions in the production environment, where legacy plugins could be encountered.

The problem is that this exception effectively botches the whole Compose action and no exports are imported. I would have preferred that the mismatching IPlugin implementations are simply ignored, so that other exports in the catalog(s), implementing the correct version of IPlugin, are still imported.

Is there a way to accomplish this? I'm thinking either of several potential options:

  • There is a flag to set on the CompositionContainer ("ignore failing imports") prior to or when calling Compose
  • There is a similar flag to specify on the <ImportMany()> attribute
  • There is a way to "hook" on to the iteration process underlying Compose(), and be able to deal with each (failed) import individually
  • Using strong name signing to somehow only look for imports implementing the current version of IPlugin

Ideas?

解决方案

I have also run into a similar problem.

If you are sure that you want to ignore such "bad" assemblies, then the solution is to call AssemblyCatalog.Parts.ToArray() right after creating each assembly catalog. This will trigger the ReflectionTypeLoadException which you mention. You then have a chance to catch the exception and ignore the bad assembly.

When you have created AssemblyCatalog objects for all the "good" assemblies, you can aggregate them in an AggregateCatalog and pass that to the CompositionContainer constructor.

这篇关于MEF:“无法加载一个或多个所请求的类型。检索LoaderExceptions以获取更多信息“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆