MEF container hierarchy and GetExports<T>

Jan 26, 2012 at 7:10 AM

hallo, maybe someone could answer the following question from stackoverflow.

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?

Jan 26, 2012 at 5:11 PM

Thanks for getting in touch. This is a known limitation – I’ve followed up on your Stack Overflow post with details of a possible workaround: http://stackoverflow.com/questions/8999491/mef-container-hierarchy-and-getexportst/9022168#9022168

Nick

From: blindmeis [email removed]
Sent: Wednesday, January 25, 2012 11:11 PM
To: Nicholas Blumhardt
Subject: MEF container hierarchy and GetExports<T> [MEF:287447]

From: blindmeis

hallo, maybe someone could answer the following question from stackoverflow.

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?