Hopeless
Hopeless

Reputation: 4763

Get exported metadata without using ImportAttribute or ImportManyAttribute in MEF?

I believe that the ImportAttribute or ImportManyAttribute behind the scenes should use some core methods of MEF to get the exported metadata paired with the actual instance of the exported type. Using those attributes works fine with the following setup:

//the metadata interface
public interface IMetadata {
    string Name {get;}
}
//the custom ExportAttribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public class CustomExportAttribute : ExportAttribute, IMetadata {

    public string Name {get;set;}
}
//the class which need to be exported (both value and metadata)
[CustomExport(Name = "someName")]
public class A {
}
//the class which imports the exported value and metadata
[Export]
public class B {
    [Import]
    public Lazy<A, IMetadata> AData {get;set;}
}

Now when getting the exported value of B, I can browse the AData with correctly exported instance of A and its associated metadata via IMetadata interface, like this:

var ac = new AggregateCatalog();
ac.Catalogs.Add(new DirectoryCatalog("."));
var c = new CompositionContainer(ac);
var b = c.GetExportedValue<B>();
var data = b.AData.Value;//some instance of A here
var mdata = b.AData.Metadata;//some metadata of A here

However I don't want to use the class B in this case, how could I obtain the exported pair of instance of A and its metadata? Because not using any class (like B), the attribute ImportAttribute is also not used in this case. Here is what I've tried:

var ac = new AggregateCatalog();
ac.Catalogs.Add(new DirectoryCatalog("."));
var c = new CompositionContainer(ac);
var a = c.GetExportedValue<Lazy<A,IMetadata>>();

The last line above throws the exception ImportCardinalityMismatchException, like this:

No exports were found that match the constraint: ContractName System.Lazy(Test.A,Test.IMetadata) RequiredTypeIdentity System.Lazy(Test.A,Test.IMetadata)

I believe that there must be some way to get the exported value (pair of type instance and its metadata) directly without using a dummy class in which the ImportAttribute is used to store the exported value in some property of that class.

I'm still getting started with MEF and Prism.

Upvotes: 2

Views: 482

Answers (1)

taquion
taquion

Reputation: 2767

There is a way indeed! No need for the export to be imported in another class. Just use GetExport< T, TMetadataView > method. Based on your code I made it work only by adding:

var wow = c.GetExport<A, IMetadata>();

This returns just what you want, a Lazy < T, TMetadataView >

Hope this helps!

Upvotes: 1

Related Questions