如何通过类名获得MEF导出值?

时间:2015-01-29 21:47:02

标签: c# mef

我有一个名为MainWindow的窗口和一个名为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获得导出值?

1 个答案:

答案 0 :(得分:3)

因为allExports是IEnumerable&lt;懒惰&LT; T>&gt;您无法在不创建关联值的情况下(通过调用.Value)获取每个导出类型,然后检查值类型。创造所有价值观并不是一件好事。你只能通过分析typeof(Lazy&lt; T&gt;)来获得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"