MEF for Beginner – Part 5 (Import)

2010/01/02

MEF for Beginner – Part 5 (Import)

this is the 5th post on MEF for beginner series, you can see the previous post here, here and here.

this post will focus on the Import aspect.

we will soon learn about the different signature that can be apply with the Import decoration,

but before starting with that, we should introduce the Lazy<T> class

which is a first citizen at the MEF world, and part of the CLR 4 types.

 

Lazy<T> definition

Lazy<T> is used in order of delaying the actual instantiation until it actually needed.

in fact using Lazy<T> the actual instantiation will occur the first time the Value property is accessed or ToString method is called.

you can use the Lazy<T> when ever you want to delay the actual instantiation of the

object that were discovered by the MEF composition.

 

The Import / ImportMany decorations

MEF is trying to discover parts that apply to Import definition constraint.

we can think at the Import definition as a where clause of the Linq query

(the from clause will be define by the Catalog / Export provider which will discuss latter on this series).

out of the box MEF offer an attribute model for the Import definition.

 

Decoration options

out of the box MEF is offering 2 type of Import decorations:

1. [Import] for single discoverable part.

2. [ImportMany] for discovering multiple parts. 

Note: you should use [ImportMany] if there is a possibility that MEF will discover multiple Exported parts

even if you need only one of those parts (you can latter filter one using Linq query).

if you ask for single part and MEF discovering multiple it will throw an exception or return null

(depending on the MEF policy which will discuss in the next post on this series).

 

Import single instance

as I said in the previous paragraph, you should not use the [Import] attribute unless

you really expecting single discovery (like the case of discovering UI shell).

you apply the [Import] decoration to properties that having a getter and a setter (the setter can be private),

actually you can decorate a private property too (not in Silverlight).

Note: you can also decorate fields but it considered as bad practice.

and you can use the Lazy<T> if you want delay instantiation.

Import decoration may look like the following code:

Code Snippet
  1.  
  2. [Import]
  3. public ISay Hellow { get; private set; }
  4.  
  5. [Import]
  6. public Lazy<ISay> HellowLazy { get; private set; }

in the sample above the Import contract is concluded from the type of the property,

while in the next sample it is explicitly define.

note that the Lazy<T> is not part of the contract.

Code Snippet
  1.  
  2. [Import(typeof(ISay))]
  3. public ISay Hellow { get; private set; }
  4.  
  5. [Import(typeof(ISay))]
  6. public Lazy<ISay> HellowLazy { get; private set; }

using explicit contract is useful while we want MEF to search for contract of specific derived

type and not for the type of the property itself.

in case that the Imported property can have null value you should add the AllowDefault=true

to the Import decoration ( it will look like the following [Import (AllowDefault=true)] ).

 

Import multiple values

Importing multiple values is done by using the [ImportMany] attribute.

we can assign this attribute to properties that having IEnumerable<T>, Array ([]) and

any type that derived from ICollection<T>.

the types within the above sets can be Lazy<T> for having delay instantiation.

the following code snippet will demonstrate the use of [ImportMany] decoration:

Code Snippet
  1. [ImportMany]
  2. public ISay[] AsArray { get; private set; }
  3.  
  4. [ImportMany]
  5. public IEnumerable<ISay> AsEnumerable { get; private set; }
  6.  
  7. [ImportMany]
  8. public List<ISay> AsCollection { get; private set; }
  9.  
  10. [ImportMany]
  11. public Lazy<ISay>[] AsLazyArray { get; private set; }
  12.  
  13. [ImportMany]
  14. public IEnumerable<Lazy<ISay>> AsLazyEnumerable { get; private set; }
  15.  
  16. [ImportMany]
  17. public List<Lazy<ISay>> AsLazyCollection { get; private set; }

 

Construction time import

the last capability I’m going to discuss in this post,

is one that I advice against using whenever you can, because it can lead to

cross composition reference. just for knowing what to avoid from

I will now introduce you to the [ImportingConstructor].

the [ImportingConstructor] can be decorate constructor that should be use by

the MEF composition, so any parameter of this constructor is

treated as import which should be satisfied.

the constructor may look as follow:

Code Snippet
  1. [ImportingConstructor]
  2. public Rumors(ISay hello)
  3. {
  4. }

 

Summary

in this post we learn which signature can be apply to the import definitions

and we present the Lazy<T> type and its role under the MEF world.

on the next post at this series we will survey different MEF policies that

can affects the behavior of the MEF composition process.

 

code snippet (console application) can be download from here.

 

תגים של Technorati:‏ ,,,,,


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>