MEF 的 GetExports<T、TMetadataView>() 无法在 CompositionContainer 中找到组合部分



当尝试使用GetExports()(使用下面描述的LINQ查询)加载实例化的导出时,该方法返回null。我注意到,在不使用LINQ查询的情况下调用GetExports时,返回值是Count: 0。这将向我表明,MEF未能找到任何已在集装箱中组成的出口。但是,在查看Container.Catalog.Parts.ExportDefinitions时,我可以看到ExportDefinition。对我在哪里出错有什么想法吗?在查询之前,一切似乎都运行良好。

我声明并实现了以下合约和元数据视图:

public interface IMap
{
    void Init();
    int ParseData();
}
public interface IMapMetadata
{
    string MapName { get; }
    string DocumentType { get; }
}
[Export(typeof(IMap))]
[ExportMetadata("MapName", "Map")]
public class Map
{
    public Map()
    {
    }
}

我使用以下代码来加载包含满足此契约的dll的目录:

    public void LoadByDirectory(string zPath)
    {
        try
        {
            _catalog.Catalogs.Add(new DirectoryCatalog(zPath));
        }
        catch (Exception e)
        {
            String zErrMess = e.Message;
        }
    }

使用LINQ查询获取导出:

public IMap GetMapInstance(string zMapName)
{
        IMap ndeMap;
        _container = new CompositionContainer(_catalog);
        _container.ComposeParts(this);
        try
        {
            ndeMap = _container.GetExports<IMap, IMapMetadata>()
                            .Where(p => p.Metadata.MapName.Equals(zMapName))
                            .Select(p => p.Value)
                            .FirstOrDefault();
        }
        catch (Exception ex) 
        {
            throw new Exception("Failed to load map " + zMapName + ": " + ex.Message, ex);
        }
        return ndeMap;
    }

像这样调用上面的方法:

IMap map = mapFactory.GetMapInstance("Map");

返回null。

除了下面的答案,我忘记在map类上声明接口,这解决了这个问题(注意我删除了DocumentType属性):

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MapExportAttribute : ExportAttribute, IMapMetadata
{
    public MapExportAttribute()
        : base(typeof(IMap))
    {
    }
    public string MapName { get; set; }
}
[MapExport(MapName="Map")]
public class Map : IMap
{
    public Map()
    {
    }
    public void  Init()
    {
        throw new NotImplementedException();
    }
    public int  ParseData()
    {
        throw new NotImplementedException();
    }
}

看起来您丢失了导出中的DocumentType元数据:

[Export(typeof(IMap))]
[ExportMetadata("MapName", "Map")]
[ExportMetadata("DocumentType", "???")]
public class Map
{
}

确保指定正确的元数据的最简单方法是自定义导出属性:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MapExportAttribute : ExportAttribute, IMapMetadata
{
   public MapExportAttribute() : base(typeof(IMap))
   {
   }
   public string MapName { get; set; }
   public string DocumentType { get; set; }
}
[MapExport(MapName = "Map")]
public class Map
{
}

相关内容

  • 没有找到相关文章

最新更新