是否可以将现有的实例注入到MEF插件中?

本文关键字:注入 MEF 插件 实例 是否 | 更新日期: 2023-09-27 18:10:34

我们正在创建一个使用MEF支持插件的应用程序。我们正在确定用户能够创建什么类型的插件,并希望使用依赖注入为这种类型的插件提供所需的数据。

例如,我们制作了一个能够显示列表的插件。要实现这一点,它需要IRepository的现有实例,用于列表将显示的数据类型。

IRepository是在数据上下文类的其他地方创建的,所以我们不能让MEF自己创建IRepository的实例。

我的想法是通过importingconstructor将IRepository的现有实例注入到插件中,但是要做到这一点,我需要使已经实例化的IRepository为MEF所知,而且我还没能弄清楚如何做到这一点。

是否可以将现有的实例注入到MEF插件中?

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

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

但是这将只允许存在一个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容器的机制来组合。