Conditional Export with MEF

Today I had a request.

I needed to export a class in a way that is was not normally exported unless, I specify some additional information that indicates that I needed it.

Some kind of conditional exporting.

So lets say we had this interface:

    public interface IRule
    {

    }

And I have two rules:

[Export(typeof(IRule))]
    public class MyRule
    {

    }

 [Export(typeof(IRule))]
    public class ConditiionalMyRule
    {

    }

But I don't want to get ConditionalMyRule unless I provide a parameter.

The solution I ended up doing was the following:

I created a new interface:

public interface IConditional {
}

I changed the export for my rule to:

[Export(typeof(IConditional))]
    public class ConditionalMyRule : IRule, IConditional
    {

    }

And when I want to get the conditional rules I do something like this:

var appContainer = new ApplicationCatalog();
var container = new CompositionContainer(appContainer);
var rules = container.GetExportedValues<IConditional>().Cast<IRule>();

I do not love this code. I know I can add metadata and do something like:

  public interface IFeatureMetadata
    {
        string Feature { get; }
    }

    [Export(typeof(IRule))]
    [ExportMetadata("Feature", "Feature1")]
    public class Rule3 : IRule
    {

    }

And then get the particular export with code like:

            var appContainer = new ApplicationCatalog();
            var container = new CompositionContainer(appContainer);

            var r = container.GetExports<IRule, IFeatureMetadata>()
                           .Where(e => e.Metadata.Feature.Equals("Feature1"))
                           .Select(e => e.Value)
                           .FirstOrDefault();

But in my case I cannot change how the original exports were obtained.

But its nice to play with MEF options. Maybe next time.