MEF, Import by custom condition
-
Thursday, March 17, 2011 8:03 AM
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
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

