1

我有一个简单的 MEF 从目录加载一些 dll(插件)的实现。这在 MEF1 下运行良好,但现在我想使用与 MEF2 相同的功能,它为我提供了一个 IEnumerable,其中包含目录中正确数量的 dll,但所有程序集都相同。

例如,我有两个程序集:目录中有 fakeplugin1.dll 和 fakeplugin2.dll。他们导出 FakePlugin1 和 FakePlugin2 类。现在,当我调用 container.ComposeParts() 时,列表中没有任何用 ImportMany 装饰的内容,而 container.Catalog 在目录中包含两个程序集,但它们都是 FakePlugin1。

这是代码:

[ImportMany(typeof (IDCPlugin))]
        IEnumerable<IDCPlugin> workplaceControllers;
var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory);
var agcatalogue = new AggregateCatalog(catalog);
var container = new CompositionContainer(agcatalogue);
container.ComposeParts();

我正在尝试使用 ExportFactory 和 RegistrationBuilder,但我刚刚意识到即使是基本功能也无法按预期工作。

我究竟做错了什么?我应该知道 MEF2 有什么变化吗?如何加载两个不同的程序集?:)

提前感谢您的帮助!

编辑: 它总是在文件夹中创建第一种类型的两个实例(在 abc 中升序)。如果我将另一个放在文件夹中,它会创建三个相同的,等等。

编辑:我已将代码上传到 pastebin,与 MEF2 给出相同的结果:http: //pastebin.com/3fWcujPS

4

1 回答 1

1

目录将包含检测到的任何内容的导入和导出定义。不管你是否真的需要它。

这是 MEF 的“功能”。您将需要ImportMany选择性地过滤您需要的插件。

那么如何优雅地处理多个插件呢?尝试这个:

[Export]
public class PluginService
{
   public const string BEST_PLUGIN = "BestPlugin";

   [ImportMany]
   public IEnumerable<Plugin> Plugins{ private get; set; }

   [Export(BEST_PLUGIN)]
   public Plugin BestPlugin{ get { return GetBestPlugin(); } }

   Plugin GetBestPlugin()
   {
       return Plugins.FirstOrDefault(); //or some other logic for selection
   }
}

如果您的插件是资源密集型的,您可能需要考虑延迟初始化。

Lazy<T, TMetadata>是 MEF 提供的一种类型,用于保存对导出的间接引用。在这里,除了导出对象本身之外,您还可以获得导出元数据,或描述导出对象的信息。每个都Lazy<T, TMetadata>包含一个IOperation 表示实际操作的对象和一个IOperationData 表示其元数据的对象。

http://msdn.microsoft.com/en-us/library/dd460648.aspx#further_imports_and_importmany

MEF 对组件基数(事物的数量)有严格的规则,以确保永远不会有任何意外,但这确实意味着您必须小心部署。

于 2013-10-09T12:13:47.843 回答