This project has moved and is read-only. For the latest updates, please go here.

Export is there but ExportFactory is not?

Jul 22, 2010 at 7:50 AM
Edited Jul 22, 2010 at 12:34 PM

Why would this work:

var entity1 = Container.GetExportedValue<MyEntity>();

...but not...

var entity2 = Container.GetExportedValue<ExportFactory<MyEntity>>();

I can't figure out why. I just get this error. And it's true that there is no such part, but this has always worked before. I should be able to pull on my export as an ExportFactory`1 without making any changes as long as the PartCreationPolicy is anything but Shared, which it is. I'm using the MEF 2 Preview getting the 404 equivalent of MEF.

No exports were found that match the constraint '((exportDefinition.ContractName = "System.ComponentModel.Composition.ExportFactory(MyEntity)") && (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") && "System.ComponentModel.Composition.ExportFactory(MyEntity)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.

Any advice on how to debug this?

Jul 22, 2010 at 1:41 PM

I believe the answer for the above is that you just can't do it. Found this thread by Wes - "You cannot get an ExportFactory back from a direct query on the container"

So i figured maybe I could do this:

    public class Factory<T>
        public IEnumerable<ExportFactory<T>> Factories { get; private set; }

        public Factory(IEnumerable<ExportFactory<T>> factories)
            this.Factories = factories;

I was then reminded that MEF does not support open generic types. Which this is. And while on that topic. Can we expect open generic type support in the near future? I know that Glenn blogged about this but then I have to grab that from MEF Contrib and I want to avoid that. Is there maybe some other way I can leverage this in a generic fashion? So that in the end, I can do:


...and it will work! I should already be able to do this but it will have to create a strongly typed object for each type which seems a bit verbose.

Jul 22, 2010 at 7:52 PM
Edited Jul 22, 2010 at 7:54 PM

You can do it with some slight modification to your approach by making it a buddy part. 

public class Factory<T> { 
  public IEnumerable<ExportFactory<T>> Factories { get; set; } 

Now you can new up a closed instance of Factory<T> and call SatisfyImportsOnce on the container to get the factories. 

var factory = new Factory<Foo>(); 
container.SatisfyImportsOne(factory); //satisfies the factories import

 I haven't tested this exactly, but it should work. The reason why this is needed is because ExportFactory relies on a specific ImportDefinition that we create under the hood for imports on parts. This works because in this case we dynamically create an import of ExportFactory. Glenn

Jul 22, 2010 at 7:55 PM
Edited Jul 22, 2010 at 7:58 PM

Oh yeah, that should work, I'll try that, thanks!

I just know there were line breaks in that post that went missing ;) There's something wierd about these forms... your post when I first read it was a giant single paragraph blob.

Jul 22, 2010 at 7:58 PM

Try refreshing on codeplex..>I fixed the breaks

Jul 22, 2010 at 7:59 PM

Yeah, it's all good now :)