Uzamčený MEF, Import by custom condition

  • Thursday, March 17, 2011 8:03 AM
     
      Has Code

    Hi, everyone.

    I have some extensible type:

     

    public abstract class Extensible
    {
     protected IEnumerable<IExtension> Extensions { ... }
    }
    

     

    where IExtension is the interface of extensions (a.k.a. plugin, addin, etc).

    There's may descendants of Extensible. Each descendant type has its own set of extensions, therefore I need to filter all available implementations of IExtension by some criteria, to initialize collection of extensions correctly.

     

    If I would do this manually, I would use such logic: make a custom attribute, e.g. ExtensionAttribute, and pass the type of the concrete Extensible in attribute's constructor:

     

    public class ExtensionAttribute : Attribute
    {
     public ExtensionAttribute(Type extensibleType)
     {
      ...
     }
    }
    
    public class MyExtensible : Extensible
    {
     ...
    }
    
    [Extension(typeof(MyExtensible))]
    public class MyExtension : IExtension
    {
    }
    

    Then I would load assemblies, iterate through types, search IExtension implementations and so on.

    But how can I do this with MEF?

    Here's variants, that have struck:

    1) Make ExtensionAttribute a descendant of MEF's ExportAttribute. But how and when I can apply filter?

    2) Make a "marker" interface for extensions, intended for the concrete Extensible, and use its type in ExportAttribute:

     

    public interface IMyExtension : IExtension
    {
    }
    
    [Export(typeof(IMyExtension))]
    public class MyExtension : IMyExtension
    {
    }
    

     

    But I don't want to make many superfluous types.

    I addition, I can't understand, how to apply custom import condition, which cannot be described by metadata: e. g., "do not load extensions, which type name starts with "A" on Wednesdays". Yes, I know that example is very artificial, but nevertheless...

     

All Replies

  • Thursday, March 17, 2011 9:20 AM
     
     Answered Has Code

    One good solution may be:

    1-Create a class to define the Metadata atributes that you need to discriminate the kind of plugin:

     [MetadataAttribute]
      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
      public class YourPlugInMetadata : ExportAttribute, IYourPlugInMetadata <br/>  {
        public string KindOfPlugIn{ get; set; }
        public YourPlugInMetadata (string kindOfPlugIn) 
        {<br/>    }<br/>
        ...
      }
    

    2-Decorate the plugins with the concrete information:

    [Export(typeof(IXXXProvider))]
      [YourPlugInMetadata ("PlugINForYYYFeature")]
      public class YYYFeatureProvider : ...
      {
       ...
      }

    And now you can query the metadata when you are composing the container with the Metadata property of the composed object.


    Please mark posts as answers/helpful if it answers your question
    • Marked As Answer by Dennis Petrov Thursday, March 17, 2011 9:46 AM
    •  
  • Thursday, March 17, 2011 9:46 AM
     
     

    Thanks, Andoni.

     

    I've found more complete explanation here:

    http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/20/mef-for-beginner-metadata-part-8.aspx