ImportDefinition and Metadata

Aug 6, 2009 at 10:00 AM

I finally found the time to try out MEF and I really like it. But I'm a bit surprised that it does only support static composition, meaning all exports need to be attributed and compiled. There is no way to add an export through configuration.

So I tried to add dynamic exports by writing a ComposablePartCatalog, which makes it possible to add dynamic exports. But that is only possible if you know the ExportTypeIdentity, contract name and metadata of the imports beforehand. The problem here is that ImportDefinition does not expose the metadata and only exposes the constraint property and IsConstraintSatisfiedBy() method. Even the ExportTypeIdentity is not exposed in the ImportDefinition class. But on the other hand, the complied constrained of ImportDefinition relies on the Metadata property of the ExportDefinition class.

Short example why this could actually be useful: If, for example, I use the IMessageSender imports in my application and want to provide a default implementation for all imports of IMessageSender where no applicable exports exists, I'm unable to do that because I don't even know which ExportTypeIdentity the ImportDefinition represents. By adding Metadata to ImportDefinition I would be able to do that and it would make ImportDefinition and ExportDefinition symetrical.

Actually I would even like to go a step further and use the contract name and metadata to configure my exports, so an import for IEmailSender and contract name "Sales" could use the same type as an import for IEmailSender and contract name "HumanResources", but the actual instances would be configured differently (for example they would use different email addresses).

Aug 6, 2009 at 5:52 PM

What you're looking for may be along the lines of this feature in MEF Contrib: http://mefcontrib.codeplex.com/Wiki/View.aspx?title=Provider%20Model%20Fluent%20Definition%20Provider&referringTitle=Provider%20model

There are many possible programming models for MEF - the attribute-based syntax that we provide out-of-the-box is optimised for discoverability, as this is a core part of the extensibility (as opposed to internal composition) scenarios. In the future we may investigate programming models for other use cases like the one you've described.

Nick

Coordinator
Aug 7, 2009 at 12:21 AM

Also, take a look at ContractBasedImportDefinition.  All imports coming from the attributed programming model will be instances of this class, so you can try casting the ImportDefinition to ContractBasedImportDefinition, and if it succeeds you can get the information you need from its properties.

Daniel

Aug 7, 2009 at 10:34 AM
nblumhardt wrote:

What you're looking for may be along the lines of this feature in MEF Contrib: http://mefcontrib.codeplex.com/Wiki/View.aspx?title=Provider%20Model%20Fluent%20Definition%20Provider&referringTitle=Provider%20model

 Actually looking at the contrib project was first thing I did. However it cannot handle wildcard definitions because the DefinitionProviderPartCatalog just overrides the Parts property of ComposablePartCatalog and not GetExports(), which would be neccessary to handle that use case because the logic is hidden inside ImportDefinition and not ExportDefinition.

That brings me to the question why? Wouldn't it be better more flexible to if the exports checks if it can satisfy the import constraints, i.e. someExportDefinition.Satisfies( someImportDefinition )?

dsplaisted wrote:

Also, take a look at ContractBasedImportDefinition.  All imports coming from the attributed programming model will be instances of this class, so you can try casting the ImportDefinition to ContractBasedImportDefinition, and if it succeeds you can get the information you need from its properties.

Daniel

 Thanks for the tip. I have already made a small proof-of-concept implementation that actually does that. But I think that casting is ugly and may break the code in the future. Right now it looks like I have to go down that road.

Michael