尝试使用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。
已更新
除了下面的答案,我忘了在地图类上声明接口,这解决了问题(注意我删除了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();
}
}
答案 0 :(得分:1)
您似乎错过了导出中的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
{
}