使用新的流畅的MEF编程模型,如果我有多个目录:


我将RegistrationBuilder传递到哪个目录?
我是否需要将RegistrationBuilder传递给SatisfyImportsOnce通话?
我使用哪个SatisfyImportsOnceComposeParts? (流利的MEF对此有什么改变吗?)


例如。这是一个说明我的困惑的示例(请参阅有关r.h.s的评论):

// Get pre-wired registration builder
RegistrationBuilder rb = new MefCompositionRoot().CommonRegistrationBuilder();

// Register this WCF service class
rb.ForType<LogService>().Export<LogService>();


var assembly = typeof (LogService).Assembly;
var assemblyCatalog = new AssemblyCatalog(assembly, rb); // <-- HERE?
var dirCatalog = new DirectoryCatalog("bin", rb);   // <-- and HERE?

// Combine catalogs
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(dirCatalog);
catalog.Catalogs.Add(assemblyCatalog);

var container = new CompositionContainer(catalog);

container.SatisfyImportsOnce(this, rb);//  THIS?
container.ComposeParsts(this); ///or THIS?

最佳答案

您可以将RegistrationBuilder放在要与MEF约定一起使用的任何目录中。如果只想使用Conventions Model,则在所有目录中使用它。如果示例代码中的DirectoryCatalog将加载仅包含归因导出/导入的程序集,则您不需要RegistrationBuilder。请注意,两个模型(属性模型和竞争模型)可以共存。因此,您可以将RegistrationBuilder添加到所有目录中,除非可能存在不希望在CompositionContainer中使用的规则(使用RegistrationBuilder配置)的类型。
SatisfyImportsOnce的重载是一个谜。从文档(以及对MEF的源代码的快速浏览)看来,您可以临时使用特定的RegistrationBuilder。实际上,我仅设法将其与以下代码示例一起使用。
SatisfyImportsOnce禁用重新组合。查看有关此主题的excellent answer




使用SatisfyImportsOnce(Object,ReflectionContext)的示例

private static void TestLateRegistration_SameBuilder_Ok()
{
    var rb = new RegistrationBuilder();
    var assemblyCatalog = new AssemblyCatalog(typeof(LogService).Assembly, rb);

    using (var container = new CompositionContainer(assemblyCatalog))
    {
        rb.ForType<LogService>().Export();
        var server = new TypeImportingLogService();
        //Use the same RegistrationBuilder.
        container.SatisfyImportsOnce(server, rb);
    }
}

10-02 07:40