title: Trouble with MEF ExportFactory and batch exports
body: <p>We are running into an issue when using an ImportMany that uses an ExportFactory with MEF where exports composed with a CompositionBatch are rejected.  Below is an example program that works fine:</p>
  
  <pre><code>class Program
  {
      public CompositionContainer Container;
      private Program()
      {
          var catalog = new AggregateCatalog();
          catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
          Container = new CompositionContainer(catalog);
          Container.ComposeParts(this);
      }
  
      public interface ICalculator
      {
          String Calculate(String input);
      }
  
      public class MyOtherCalculator : ICalculator
      {
          public string Calculate(string input)
          {
              return "blah";
          }
      }
  
      [Export]
      public class CalculatorCollection
      {
          [ImportMany(typeof(ICalculator))]
          public IEnumerable&lt;Lazy&lt;ICalculator, ICalculatorMetadata&gt;&gt; calculators;
      }
  
      static void Main(string[] args)
      {
          var p = new Program();
  
          var typeName = typeof(ICalculator).FullName;
          var batch = new CompositionBatch();
          var metadata = new Dictionary&lt;string, object&gt;();
          metadata[CompositionConstants.ExportTypeIdentityMetadataName] = typeName;
          metadata["Name"] = "blah blah blah";
          var definition = new ExportDefinition(typeName, metadata);
  
          batch.AddExport(new Export(definition, () =&gt; new MyOtherCalculator()));
          p.Container.Compose(batch);
  
          var collection = p.Container.GetExportedValue&lt;CalculatorCollection&gt;();
          var calculator = collection.calculators.First().Value;
      }
  }
  
  public interface ICalculatorMetadata
  {
      string Name { get; }
  }
  </code></pre>
  
  <p>But, if I change the ImportMany on the CalculatorCollection to use an ExportFactory</p>
  
  <pre><code>[Export]
      public class CalculatorCollection
      {
          [ImportMany(typeof(ICalculator))]
          public IEnumerable&lt;ExportFactory&lt;ICalculator, ICalculatorMetadata&gt;&gt; calculators;
      }
  </code></pre>
  
  <p>it will no longer contain the export composed through the batch.  We did find a workaround, shown below, but it seems like a dirty hack as it relies on the use of internal type names and the export needs to know that it will be imported with an Export Factory.</p>
  
  <p>Does anyone know the proper way to fix the batch export?</p>
  
  <p>Thanks for any help.</p>
  
  <p>Workaround program:</p>
  
  <pre><code>class Program
  {
      public CompositionContainer Container;
      private Program()
      {
          var catalog = new AggregateCatalog();
          catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
          Container = new CompositionContainer(catalog);
          Container.ComposeParts(this);
      }
  
      public interface ICalculator
      {
          String Calculate(String input);
      }
  
      public class MyOtherCalculator : ICalculator
      {
          public string Calculate(string input)
          {
              return "blah";
          }
      }
  
      [Export]
      public class CalculatorCollection
      {
          [ImportMany(typeof(ICalculator))]
          public IEnumerable&lt;ExportFactory&lt;ICalculator, ICalculatorMetadata&gt;&gt; calculators;
      }
  
      public class MyComposablePartDefinition : ComposablePartDefinition
      {
          private ExportDefinition _definition;
  
          public MyComposablePartDefinition()
          {
              var typeName = typeof(ICalculator).FullName;
              var batch = new CompositionBatch();
              var metadata = new Dictionary&lt;string, object&gt;();
              metadata[CompositionConstants.ExportTypeIdentityMetadataName] = typeName;
              metadata["Name"] = "blah blah blah";
              var definition = new ExportDefinition(typeName, metadata);
  
              var contractName = "System.ComponentModel.Composition.Contracts.ExportFactory";
              var typeName2 = typeof(ComposablePartDefinition).FullName;
              var metadata2 = new Dictionary&lt;string, object&gt;();
              metadata2[CompositionConstants.ExportTypeIdentityMetadataName] = typeName2;
              metadata2["ProductDefinition"] = definition;
              metadata2["Name"] = "some factory";
              Func&lt;object&gt; factoryFactory = () =&gt;
                  new ExportFactory&lt;ICalculator&gt;(
                      () =&gt; Tuple.Create&lt;ICalculator, Action&gt;(new MyOtherCalculator(), () =&gt; { }));
  
              _definition = new ExportDefinition(contractName, metadata2);
          }
  
          public override ComposablePart CreatePart()
          {
              return new MyComposablePart(_definition);
          }
  
          public override IEnumerable&lt;ExportDefinition&gt; ExportDefinitions
          {
              get { return new[] { _definition }; }
          }
  
          public override IEnumerable&lt;ImportDefinition&gt; ImportDefinitions
          {
              get { return Enumerable.Empty&lt;ImportDefinition&gt;(); }
          }
      }
  
      private class MyComposablePart : ComposablePart
      {
          private ExportDefinition _definition;
          public MyComposablePart(ExportDefinition def)
          {
              _definition = def;
          }
  
          public override IEnumerable&lt;ExportDefinition&gt; ExportDefinitions
          {
              get { return new[] { _definition }; }
          }
  
          public override object GetExportedValue(ExportDefinition definition)
          {
              return new MyOtherCalculator();
          }
  
          public override IEnumerable&lt;ImportDefinition&gt; ImportDefinitions
          {
              get { return Enumerable.Empty&lt;ImportDefinition&gt;(); }
          }
  
          public override void SetImport(ImportDefinition definition, IEnumerable&lt;Export&gt; exports)
          {
          }
      }
  
  
      static void Main(string[] args)
      {
          var p = new Program();
  
          var typeName = typeof(ICalculator).FullName;
          var batch = new CompositionBatch();
          var metadata = new Dictionary&lt;string, object&gt;();
          metadata[CompositionConstants.ExportTypeIdentityMetadataName] = typeName;
          metadata["Name"] = "blah blah blah";
          var definition = new ExportDefinition(typeName, metadata);
  
          var contractName = "System.ComponentModel.Composition.Contracts.ExportFactory";
          var typeName2 = typeof(ComposablePartDefinition).FullName;
          var metadata2 = new Dictionary&lt;string, object&gt;();
          metadata2[CompositionConstants.ExportTypeIdentityMetadataName] = typeName2;
          metadata2["ProductDefinition"] = definition;
          metadata2["Name"] = "some factory";
          Func&lt;object&gt; factoryFactory = () =&gt;
              new ExportFactory&lt;ICalculator&gt;(
                  () =&gt; Tuple.Create&lt;ICalculator, Action&gt;(new MyOtherCalculator(), () =&gt; { }));
  
          batch.AddExport(new Export(definition, () =&gt; new MyOtherCalculator()));
          batch.AddExport(new Export(new ExportDefinition(contractName, metadata2), () =&gt; new MyComposablePartDefinition()));
          p.Container.Compose(batch);
  
          var collection = p.Container.GetExportedValue&lt;CalculatorCollection&gt;();
          var calculator = collection.calculators.First().CreateExport().Value;
      }
  }
  
  public interface ICalculatorMetadata
  {
      string Name { get; }
  }
  </code></pre>