能否将现有的实例注入到MEF插件中?

4
我们正在创建一个支持使用MEF插件的应用程序。我们正在确定用户能够创建哪种类型的插件,并希望使用依赖注入来为这种类型的插件提供所需的数据。
例如,我们制作了一个能够显示列表的插件。为了实现这一点,它需要显示列表所需数据类型的现有IRepository实例。
IRepository是在另一个数据上下文类中创建的,因此我们无法让MEF本身创建IRepository的实例。
我的想法是通过importing constructor将现有的IRepository实例注入到插件中,但为了使其工作,我需要让已经实例化的IRepository为MEF所知道,而我还没有找到如何做到这一点。任何帮助都将不胜感激。
1个回答

8

最简单的方法是在容器中组合现有的值,例如:

var repo = // Create repo
container.ComposeExportedValue<IRepository>(repo);

但是这样只允许存在1个IRepository实例,因为它不直接控制创建的ComposablePart。如果您想要更精细的控制,可以使用CompositionBatch

var batch = new CompositionBatch();
var repo = // Create repo

var repoPart = batch.AddExportedValue<IRepository>(repo);
container.Compose(batch);

// repo will now be injected on any matching [Import] or [ImportingConstructor]

之后:
var batch2 = new CompositionBatch(null, new[] { repoPart });
var repo2 = // Get new repo

var repo2Part = batch2.AddExportedValue<IRepository>(repo2);
container.Compose(batch2);

由于我可以访问批处理提供的ComposablePart实例,因此以后可以将其删除。通常通过属性导出来导入没有属性的部件还有其他方法:

[Export(typeof(IRepository))]
public IRepository Repository
{
    get { return CreateRepository(); }
}

当然,这需要您能够在组合时创建存储库实例,这可能是可能的,也可能不可能。

最后,有一个使用替代编程模型的选项。 MEF中默认(也是最常见的)的是注释编程模型,通过利用 [Export] [Import] 属性来控制组合,但在MEFContrib中(以及即将推出的MEF2中),可以使用注册编程模型,其中部件基于类似大多数其他IoC容器的机制进行组合。


谢谢!我之前在Visual Studio中探索了CompositionContainer和CompositionBatch,但没有使用using System.ComponentModel.Composition这一行。我更习惯于使用完整的命名空间和类型,例如var compositionBatch = new System.ComponentModel.Composition.CompositionBatch()。因为容器和组合批处理上的AddExportedValue都是扩展方法,所以它们没有显示出来。现在我知道了这些方法,我可以更进一步了。再次感谢。 - Jesse van Assen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接