Declaring Imports

Composable Parts declare imports [System.ComponentModel.Composition.ImportAttribute] attribute. Similar to exports, there are several different methods namely through Fields, Properties and Constructor Parameters.

Property Imports

To import a value to a property, decorate the property with the [System.ComponentModel.Composition.ImportAttribute]. For example the snippet below imports an IMessageSender

Constructor Parameters

You can also specify imports through constructor parameters. This means that instead of adding properties for each import, you add parameters to a constructor for each import. To use this, follow the following steps.

1. Add a [System.ComponentModel.Composition.ImportingConstructorAttribute] attribute to the constructor that should be used by MEF.
2. Add parameters to the constructor for each import.

For example the code below imports a message sender in the constructor of the Program class.

Field Imports

Note: note that importing or exporting private members (fields, properties and methods) while supported in full trust is likely to be problematic on medium/partial trust.

Optional imports

MEF allows you to specify that an import is optional. When you enable this, the container will provide an export if one is available otherwise it will set the import to
Default(T). To make an import optional, set
AllowDefault=true on the import as below.

OrderController optionally imports a logger. If the logger is not present, it will set it's private
_logger to a new DefaultLogger instance otherwise it will use the imported logger.

Importing collections

In addition to single imports, you can import collections with the ImportMany attribute. This means that all instances of the specific contract will be imported from the container.

MEF parts can also support recomposition. This means that as new exports become available in the container, collections are automatically updated with the new set. For example below the Notifier class imports a collection of IMessageSender. This means if there
are 3 exports of IMessageSender available in the container, they will be pushed in to the Senders property during compositon.

IPartImportsSatisfiedNotification

In some situations it may be important for your class to be notified when MEF is done with the import process for your class instance. If that's the case implement the
[System.ComponentModel.Composition.IPartImportsSatisfiedNotification] interface. This interface has only a single method: OnImportsSatisfied, which is called when all imports that could be satisfied have been satisfied.

publicclass Program : IPartImportsSatisfiedNotification
{
[ImportMany]
public IEnumerable<IMessageSender> Senders {get; set;}
publicvoid OnImportsSatisfied()
{
// when this is called, all imports that could be satisfied have been satisfied.
}
}

PublicClass Program
Implements IPartImportsSatisfiedNotification
<ImportMany()>
PublicProperty Senders() As IEnumerable(Of IMessageSender)
PublicSub OnImportsSatisfied() Implements IPartImportsSatisfiedNotification.OnImportsSatisfied
' when this is called, all imports that could be satisfied have been satisfied. EndSubEndClass

Comments

This sentence, from the Optional Import section of this page, could use a little more explanation and it would be nice if that discussion also was reflected in the coding example. "When [optional imports], the container will provide an export if one is available otherwise it will set the import to Default(T). " The coding example did not show an example of Default(T) unless the conditional code that determines if the import is null is what was meant by "Default(T)".

When does resolution of [Import]-tagged fields happen, relative to the constructor being called? I'd originally assumed before, but now it seems like they're done after. As such it might be worth adding a note about this to underline that the [ImportingConstructor] stuff isn't just available to bring stuff into the constructor, it's actually /necessary/, because the other [Import]s won't be ready yet.

Dear Mr LazyWeb: This is one of the top two hits for ImportingConstructor example. http://stackoverflow.com/questions/2008133/mef-constructor-injection is the other and solved my issue (wanted to pass a context param). If you feel an example (of an Import attribute on a constructor arg) makes sense in here, it'd be nice to have it (but I ahvent looked at this wiki in its entirity so dont feel qualified to edit.).

Working with Preview 5 for this comment. There is an inconsistency between a constructor import and a property import when importing a collection of parts. In a property you have to use ExportCollection<T> but in the constructor you have to use Export<T>[]. Why the ExportCollection for one and Export[] for the other?