如何通过 class 名称获取 MEF 导出值?

How can I get a MEF exported value by a class name?

我有一个名为 MainWindow 的 window 和一个名为 MainWindowViewModel 的视图模型。

我想查看 MEF 的容器,看看是否可以找到 <WindowName>ViewModel

我的密码是:

CompositionContainer container;

var catalog = new AssemblyCatalog(typeof(App).Assembly);
container = new CompositionContainer(catalog);
container.ComposeParts(this);
container.SatisfyImportsOnce(this);

我看到方法了

container.GetExports(Type, Type, String)

但它只允许我导出第一个 Type 参数。我只有一个字符串名称。

我想做类似的事情

allExports.FirstOrDefault(e => e.GetType().Name.StartsWith(something))

有没有办法通过 string name 获取导出值?

由于 allExports 是 IEnumerable< Lazy< T >>,您无法在不创建关联值(通过调用 .Value)然后检查值类型的情况下获取每个导出类型。创造所有价值并不是一件好事。解析typeof(Lazy< T >),只能得到typeof(T),仅此而已

元数据是不错的选择:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportViewModelAttribute : ExportAttribute, IViewModelMetadata
{
    public ExportViewModelAttribute(Type declaredType)
        : base(null, typeof(IViewModel))
    {
        this.DeclaredType = declaredType;
    }

    public Type DeclaredType { get; private set; }
}

界面为:

public interface IViewModelMetadata
{
    Type DeclaredType { get; } 
}

然后你导出:

[ExportViewModel(typeof(MyViewModel))]
public class MyViewModel: BaseViewModel, IViewModel 
{
    [...]
}

然后使用元数据的 where 子句检索它

IViewModel vm = container.GetExports<IViewModel, IViewModelMetadata>().Where(i => i.Metadata.DeclaredType == typeof(MyViewModel)).Select(i => i.Value).FirstOrDefault();

i => i.Metadata.DeclaredType.Name == "mysearchedViewModel"