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

Jes*_*sen 4 c# mef .net-4.0

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

例如,我们制作一个能够显示列表的插件.为实现此目的,它需要IRepository的现有实例来显示列表将显示的数据类型.

IRepository是在datacontext类的其他地方创建的,因此我们无法让MEF自己创建IRepository的实例.

我的想法是通过importconstructor将现有的IRepository实例注入到插件中,但为了实现这一点,我需要让MEF知道已经实例化的IRepository,并且我无法弄清楚如何去做.任何帮助,将不胜感激.

Mat*_*ott 8

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

var repo = // Create repo
container.ComposeExportedValue<IRepository>(repo);
Run Code Online (Sandbox Code Playgroud)

但这只会允许IRepository存在1个实例,因为它不会直接控制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]
Run Code Online (Sandbox Code Playgroud)

后来:

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

var repo2Part = batch2.AddExportedValue<IRepository>(repo2);
container.Compose(batch2);
Run Code Online (Sandbox Code Playgroud)

因为我可以访问ComposablePart批处理提供的实例,所以我可以在以后删除它.还有其他方法可以导入无属性的部分,通常是通过属性导出:

[Export(typeof(IRepository))]
public IRepository Repository
{
    get { return CreateRepository(); }
}
Run Code Online (Sandbox Code Playgroud)

但是,这当然要求您能够在合成时创建存储库的实例,这可能是也可能是不可能的.

最后,可以选择使用替代编程模型.MEF中的默认(也是最常见的)是属性编程模型,您可以使用[Export][Import]属性来控制您的构图,但在MEFContrib(以及即将出现的MEF2)中,能够使用注册编程模型,其中部件基于机制类似于大多数其他IoC容器.