MEF - 是否可以列出程序集所需的所有导入(无需反射)?

MEF - is it possible to list all imports required by an assembly (without reflection)?

是否有任何优雅的 MEF 方法来列出给定程序集的给定接口的所有(属性 和构造函数)导入?

我知道我可以用反射扫描所有导出的类型,检查 [Import][ImportingConstructor] 属性(等等),但我认为 MEF 已经知道了。

优雅 太主观了,所以我希望我的解决方案符合您对优雅的概念=)

您可以使用 ReflectionModelServices class,它位于 System.ComponentModel.Composition.ReflectionModel。顾名思义,它在内部使用反射,但是它是 MEF 的一部分,而 MEF 使用反射。

当你说没有反射时,我假设你指的是直接在类型上使用反射。那么,让我们继续...

假设我们有以下内容:

internal interface IFoo { }

internal class Boo : IFoo
{
    [Import] public string SomeString;

    [ImportingConstructor]
    public Boo(int someInt) { }
}

internal class Moo : IFoo
{
    [Import] public float SomeFloat;
}

然后,无论您在何处创建目录(对我而言,它恰好在控制台应用程序的 Main 中),您都可以遍历目录的各个部分并检查每个部分的导入定义:

private static void Main(string[] args)
{
    var regBuilder = new RegistrationBuilder();
    regBuilder.ForTypesMatching(t => typeof(IFoo).IsAssignableFrom(t))
        .Export<IFoo>();
    var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), regBuilder);

    foreach (var composablePartDefinition in catalog.Parts)
        if (typeof(IFoo).IsAssignableFrom(ReflectionModelServices.GetPartType(composablePartDefinition).Value))
            foreach (var importDefinition in composablePartDefinition.ImportDefinitions)
                Console.WriteLine(
                    $"Contract name: {importDefinition.ContractName}. Is parameter (for ImportingConstructor stuff): {ReflectionModelServices.IsImportingParameter(importDefinition)}");
    Console.ReadLine();
}

这个输出是:

您可以尝试探索定义 ImportDefinition 的其他属性,例如您可能想知道基数或共享策略,它们都在那里... =)

希望对您有所帮助。