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

Combining metadata and export in same attribute

Dec 3, 2009 at 2:35 PM

Is this a supported scenario? I.e. combining metadata and export in the same attribute. The test succeds when metadata is a separate attribute.

public class MyExportAttribute : ExportAttribute, IMeta
    public MyExportAttribute() : base(typeof(IService)) {}

    public string Meta { get; set; }

public interface IMeta
    string Meta { get; }

public interface IService

[MyExportAttribute(Meta = "Hello")]
public class Service

public class Client
    public IEnumerable<Lazy<IService, IMeta>> Services { get; set; }

public class MetadataMefAssertions
    public void CanReadInstancesAndMetadata()
        var container = new CompositionContainer(new TypeCatalog(typeof(Service)));

        Client c = new Client();

        Assert.AreEqual(1, c.Services.Count());
        Assert.IsInstanceOfType(c.Services.First().Value, typeof(Service));
        Assert.AreEqual("Hello", c.Services.First().Metadata.Meta);

Dec 4, 2009 at 6:04 PM

Yes we designed specifically to support this. The one thing you may want to do is put an AttributeUsages attribute on your custom export indicating AllowMultiple=false. This way the metadata will be a single value rather than an array. For example see the export below.

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class MessageSenderAttribute : ExportAttribute
    public MessageSenderAttribute() : base(typeof(IMessageSender)) { }
    public MessageTransport Transport { get; set; }
    public bool IsSecure { get; set; }

public enum MessageTransport

Dec 10, 2009 at 3:45 PM

Thanks for fixing my code =) I should have started with the example.

Dec 10, 2009 at 4:25 PM

Is it possible to use Metadata with AllowMultiple=true? Or is it planned?

I suppose it would be right, to have several parts with different metadata instead of several parts and array metadata of every of them

Dec 10, 2009 at 9:09 PM

It is possible. The place where is most interesting is when you have loose metadata / custom metadata attributes (don't derive from export). For example imagine a [Category] metadata attribute that lets me specify multiple categories for an export.


Dec 11, 2009 at 6:48 PM

You can have as many different custom exports on a part as you need. Each one can appear once if you have AllowMultiple=False.

The problem with allowing a single attribute to appear multiple times (AllowMultiple=True) is that MEF, rather naturally, creates an IEnumerable-something (an array I think) to hold your multiple values.

When you look for the one value you are expecting, your import fails, and it can be quite difficult to track this problem down. AllowMultple=True is legal, I just would not use it except, as Glen pointed out, in cases where the metadata just screams "hey, there might be mroe than one of me" (like a category).




Dec 15, 2009 at 4:25 PM

ok, i've seen that mef creates that "IEnumerable-something (an array I think) to hold your multiple values." But I dont really understand why it does such weird thing, MetaAttribute derived from Export



public void Some(object o)


After that there will be 2 parts in the catalog(and this is OK), but WHY do those parts have both metadata attributes data?