当尝试使用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
{
}