I am using container hierarchy to control IDisposable parts lifetime. Child container is attached to the filtered catalog that contains non-shared parts. Here is a code snippet:
[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);
}
}
(FilteredCatalog class is the same that mentioned in MEF documentation).
GetExport doesn’t throw cardinality mismatch exception which indicates that there is no ambiguity (exactly one export is found). But to my surprise, GetExports() returns 2 lazy exports instead of 1.
I this a bug or this behavior is by design? How could I set up child container so that GetExports returns one export in this sample?
this is a known limitation of container hierarchies in MEF using filtered catalogs. I believe (but can’t confirm right now) that setting the import source:
Should give the behaviour you want (but only in MEF2/.NET 4.5 Developer Preview).
Hope this helps!