MEF and not created objects.

Mar 22, 2010 at 6:04 PM

My trouble is initialization property in objects that not created for the composition moment. Sample:

 

class Program
{
      pulbic static void Main()
      {
            var p = new Program();
            p.Run();
      }
     
      public void Run()
     {
          Compose();
          new Foo.Run();
     }

     public void Compose()
     {
          AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
     }
}

class Foo
{
     public void Run()
     {
            createFoo1();
            createFoo2();
            createFoo3();
            ...
     }
}

class Foo1()
{
     [Import(typeof(IPlugin, AllowRecomposition = true))]
     private IPlugin _plugin;
}

[Export(typeof(IPlugin)]
class ConcretePlugin : IPlugin
{
}

When Program.Compose() method run there are no any Foo1, Foo2, Foo3 objects (they can be created during executing time) therefore all properties (_plugin) are null. 
Does anybody know how resolve this difficult?

 

Developer
Mar 22, 2010 at 9:59 PM

If I'm understanding you correctly you are constructing some Foo object directly (not using MEF) and the imports are not being satisified. This is by design, MEF can only satisify the imports on an object instance in knows about and there are a couple of ways for MEF to know about an object, one is by using MEF to construct/get it and the other is to use the container.ComposeParts(...) passing the object instance. Only then will MEF actually satisify the imports.

Mar 23, 2010 at 8:21 AM

Thank you for the answer. Could you write a little sample with construct/getting objects using MEF?  My purpose is to have ability create objects with [Import] attributes during program execution, not only for the time Compose() calling. I know that I'm trying to use MEF instead of IoC container but the aim of researching - could MEF replace IoC container or no.

Developer
Mar 23, 2010 at 5:31 PM

The best way to get objects from MEF is to import them and only directly pull on the container for the root object.

 

[Export]
class  Foo
{
  [Import]
  private Foo1 foo1;

  [Import]
  private Foo2 foo2;
  ...
}

[Export]
class Foo1
{
  [Import]
  private IPlugin _plugin;
}

Then to bootstrap the process either:
var foo = new Foo();
container.ComposeParts(foo); // Doesn't require Foo to have ExportAttribute

or

var foo = container.GetExportedValue<Foo>() // Requires Foo to have ExportAttribute

However if you need to construct things via MEF in a more dynamic fashion you can call container.GetExportedValue<FooX>() where you need to but that requires you to have access to the container so in general you should try to avoid that and the only access to the container will be by the bootstraping code.