MEF 与 ImportMany 和 ExportMetadata

问题描述 投票:0回答:2

我刚刚开始使用托管可扩展性框架。我有一个导出的类和一个导入语句:

[Export(typeof(IMapViewModel))]
[ExportMetadata("ID",1)]
public class MapViewModel : ViewModelBase, IMapViewModel
{
}

    [ImportMany(typeof(IMapViewModel))]
    private IEnumerable<IMapViewModel> maps;

    private void InitMapView()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(ZoneDetailsViewModel).Assembly));
        CompositionContainer container = new CompositionContainer(catalog);

        container.ComposeParts(this);
        foreach (IMapViewModel item in maps)
        {
            MapView = (MapViewModel)item;                
        }
    }

这个效果很好。 IEnumerable 获取导出的类。不,我尝试更改它以使用惰性列表并包含元数据,以便我可以过滤出我需要的类(与以前相同的导出)

[ImportMany(typeof(IMapViewModel))]
    private IEnumerable<Lazy<IMapViewModel,IMapMetaData>> maps;

    private void InitMapView()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(ZoneDetailsViewModel).Assembly));
        CompositionContainer container = new CompositionContainer(catalog);

        container.ComposeParts(this);
        foreach (Lazy<IMapViewModel,IMapMetaData> item in maps)
        {
            MapView = (MapViewModel)item.Value;
        }            
    }

此后,Ienumerable 就没有元素了。我怀疑我在某个地方犯了一个明显而愚蠢的错误..

c# mef
2个回答
9
投票

它可能不匹配,因为您的元数据接口与导出的元数据不匹配。为了匹配您显示的示例导出,您的元数据界面应如下所示:

public interface IMapMetaData
{
    int ID { get; }
}

0
投票

要将元数据添加到从已应用

InheritedExport
的类派生的类中,您必须将相同的
InheritedExport
属性也应用到派生类。否则,添加到派生类中的元数据将被隐藏且不可用。

换句话说,如果您使用

Lazy<T,TMetadata>
访问应用的元数据,并且您的导入未填充,则可能意味着您没有将
InheritedExport
应用于所有派生类。该部分仍将由继承的 InheritedExportAttribute 导出,但元数据将被替换,因为这就是 InheritedExport 的工作原理。

如果您应用

Export
而不是
InheritedExport
,您最终会得到零件的另一个实例。由于某些不直观的原因,Export 包含从类派生的合约名称,而不是您指定的名称,并且必须在导入语句中明确请求。

© www.soinside.com 2019 - 2024. All rights reserved.