Service Locator: Get all exports
Asked Answered
P

3

6

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?

Print answered 8/12, 2013 at 9:44 Comment(0)
E
4

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());
}
Engadine answered 11/12, 2013 at 23:39 Comment(0)
T
0

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

Thereof answered 11/12, 2013 at 22:56 Comment(0)
T
0

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;
Tuberous answered 13/12, 2013 at 20:34 Comment(2)
How is this answer any different than @default.kramer's?Entomostracan
The declaration is the same, yet I also show you how you can have Mef inject all instances without having to reference the container/catalog directly... which is the proper way how one should use a DI framework.Tuberous

© 2022 - 2024 — McMap. All rights reserved.