MEF DirectoryCatalog多次读取相同的dll

时间:2013-10-09 10:07:40

标签: c# .net dll mef mef2

我有一个简单的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

1 个答案:

答案 0 :(得分: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   object,表示实际操作,以及IOperationData   object,表示其元数据。

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

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