C# MEF容器层次结构和GetExports<;T>;
我使用容器层次结构来控制IDisposable部件的生命周期。子容器附着到包含非共享零件的筛选目录。以下是一段代码片段:C# MEF容器层次结构和GetExports<;T>;,c#,mef,containers,hierarchy,C#,Mef,Containers,Hierarchy,我使用容器层次结构来控制IDisposable部件的生命周期。子容器附着到包含非共享零件的筛选目录。以下是一段代码片段: [Export(typeof(ITest)), PartCreationPolicy(CreationPolicy.NonShared)] class Test : ITest, IDisposable { public void Dispose() {} } public interface ITest {} class Program { static v
[Export(typeof(ITest)), PartCreationPolicy(CreationPolicy.NonShared)]
class Test : ITest, IDisposable
{
public void Dispose() {}
}
public interface ITest {}
class Program
{
static void Main()
{
// parent container to hold shared disposable parts
var cat = new AssemblyCatalog(typeof(Program).Assembly);
var parent = new CompositionContainer(cat);
// child container to hold non-shared disposable parts
var nsCat = CreateNonSharedPartCatalog(cat);
var child = new CompositionContainer(nsCat, parent);
// no cardinality mismatch exception: exactly one export found
var exp = child.GetExport<ITest>();
// lazy exports: count == 2 -- why?
var exports = child.GetExports<ITest>();
Console.WriteLine("Exports count = {0}", exports.Count());
}
static ComposablePartCatalog
CreateNonSharedPartCatalog(ComposablePartCatalog cat)
{
return new FilteredCatalog(cat,
def => def.Metadata.ContainsKey(
CompositionConstants.PartCreationPolicyMetadataName) &&
((CreationPolicy)def.Metadata[
CompositionConstants.PartCreationPolicyMetadataName]) ==
CreationPolicy.NonShared);
}
}
[Export(typeof(ITest)),PartCreationPolicy(CreationPolicy.NonShared)]
类测试:ITest,IDisposable
{
public void Dispose(){}
}
公共接口ITest{}
班级计划
{
静态void Main()
{
//用于容纳共享一次性零件的父容器
var cat=新组件目录(类型(程序).Assembly);
var parent=新组合容器(cat);
//用于容纳非共享一次性零件的子容器
var nsCat=CreateNonSharedPartCatalog(cat);
var child=新合成容器(nsCat,父级);
//没有基数不匹配异常:只找到一个导出
var exp=child.GetExport();
//延迟导出:count==2——为什么?
var exports=child.GetExports();
WriteLine(“Exports count={0}”,Exports.count());
}
静态组合部件目录
CreateNonSharedPartCatalog(ComposablePartCatalog类别)
{
返回新的过滤器目录(cat,
def=>def.Metadata.ContainsKey(
CompositionConstants.PartCreationPolicyMetadataName)&&
((CreationPolicy)def.Metadata[
CompositionConstants.PartCreationPolicyMetadataName])==
创意政策(非共享);
}
}
(FilteredCatalog类与MEF文档中提到的相同)
GetExport不会抛出基数不匹配异常,这表明不存在歧义(只找到一个导出)。但令我惊讶的是,GetExports()返回2个延迟导出,而不是1个
我认为这是一个bug还是这种行为是故意的?如何设置子容器,使GetExports在此示例中返回一个导出?这是MEF中使用筛选目录的容器层次结构的已知限制。我相信(但目前无法确认)设置导入源:
[ImportMany(Source=ImportSource.Local)]
public IEnumerable<ITest> Tests { get; set; }
[ImportMany(Source=ImportSource.Local)]
公共IEnumerable测试{get;set;}
应该给出您想要的行为(但仅在MEF2/.NET4.5开发者预览中)
希望这有帮助 有什么东西导入了ITest吗?没有,我已经在这里发布了完整的代码片段。只删除usings和FilteredCatalog类代码。感谢回复!此功能是否在CodePlex发布的MEF2 Preview5中可用?此功能的工作原理如所述,并且确实在CodePlex发布的MEF2 Preview5中可用。但是,将Source设置为ImportSource.Local将仅从子容器中提取部件,因此无法以这种方式导入非共享部件。我想做的是获取所有导出的部件(共享和非共享),但不复制。啊-我看到了问题,抱歉。同样在4.5 DP中,我们有
CompositionScopeDefinition
,它有更好的机会处理这种情况-请参阅:还有一件事:对于导出工厂,ImportSource参数被忽略。看起来像只虫子。