Question

I'm using MEF and I have two exports having the same contract type but with different contract name

Eg:

[Export("TypeA", typeof(MyPlugin))]
[Export("TypeB", typeof(MyPlugin))]

I could retrieve each exports using its respective contract name:

ServiceLocator.GetExportedValues<MyPlugin>("TypeA");

But now I wish to retrieve all instances implementing MyPlugin. is there any way I could do it?

I've tried using the following code:

ServiceLocator.GetExportedValues<MyPlugin>();

But it did not work. Apparently it is used to retrieve only implementations with no specific contract name.

Any opinion?

Was it helpful?

Solution

I would simply add a nameless export alongside every named export if you want it to be resolvable both ways. For example

// named and nameless
[Export("TypeA", typeof(MyPlugin))]
[Export(typeof(MyPlugin))]

// named nameless, again
[Export("TypeB", typeof(MyPlugin))]
[Export(typeof(MyPlugin))]

class MyPlugin { }


[TestMethod]
public void mef()
{
    var catalog = new AssemblyCatalog(this.GetType().Assembly);
    var container = new CompositionContainer(catalog);

    Assert.AreEqual(2, container.GetExportedValues<MyPlugin>().Count());
}

OTHER TIPS

You can use strongly typed Metadata export.

  1. Create a custom attribute inherited from ExportAttribute, which implements from a interface.
  2. Use this custom attribute instead of Export.

You can use Import to get the required type.

[ImportMany]
public IEnumerable<Lazy<YourType,IMetadataAttribute>> Plugins{get;private set;}

You can get futher information from MEF Documentation

Declare both types of Export

[Export(typeof(IFoo)),Export("TypeA", typeof(IFoo))]
public class Foo1 : IFoo { }

[Export(typeof(IFoo)),Export("TypeB", typeof(IFoo))]
public class Foo2 : IFoo { }

And import them using ImportMany

[ImportMany]
IFoo[] foos;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top