15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

exports ❘ 761<br />

}<br />

}<br />

Thread.Sleep(3000);<br />

return x + y;<br />

code snippet Operations/Operation2.cs<br />

Because there is more than one exported Add method available, the import definition must be changed. The<br />

attribute ImportMany is used if more than one export of the same name <strong>and</strong> type is available. This attribute<br />

is applied to an array or IEnumeration interface. ImportMany is explained with more detail in the<br />

next section. For accessing metadata, an array of Lazy can be used. The class Lazy<br />

is new in .<strong>NET</strong> 4 <strong>and</strong> is used to support lazy initialization of types on first use. Lazy<br />

derives from Lazy <strong>and</strong> supports, in addition to the base class, access to metadata information with<br />

the Metadata property. In the sample, the method is referenced by the delegate Func, which is the first generic parameter of Lazy. The second generic parameter is<br />

IDictionary for the metadata collection. The ExportMetadata attribute can be used<br />

multiple times to add more than one capability, <strong>and</strong> always consists of a key of type string <strong>and</strong> a value<br />

of type object.<br />

[ImportMany("Add", typeof(Func))]<br />

public Lazy[]<br />

AddMethods { get; set; }<br />

//[Import("Add", typeof(Func))]<br />

//public Func Add { get; set; }<br />

code snippet SimpleCalculator/Calculator.cs<br />

The call to the Add method is now changed to iterate through the collection of Lazy elements. With the Metadata property, the key for<br />

the capability is checked; if the speed capability has the value fast, the operation is invoked by using the<br />

Value property of Lazy to get to the delegate:<br />

case "+":<br />

// result = Add(oper<strong>and</strong>s[0], oper<strong>and</strong>s[1]);<br />

foreach (var addMethod in AddMethods)<br />

{<br />

if (addMethod.Metadata.ContainsKey("speed") &&<br />

(string)addMethod.Metadata["speed"] == "fast")<br />

result = addMethod.Value(oper<strong>and</strong>s[0], oper<strong>and</strong>s[1]);<br />

}<br />

// result = oper<strong>and</strong>s[0] + oper<strong>and</strong>s[1];<br />

break;<br />

Instead of using the attribute ExportMetadata, you can create a custom export attribute class that derives<br />

from ExportAttribute. The class SpeedExportAttribute defines an additional Speed property that is of<br />

type Speed:<br />

using System;<br />

using System.ComponentModel.Composition;<br />

namespace Wrox.ProCSharp.MEF<br />

{<br />

public enum Speed<br />

{<br />

Fast,<br />

Slow<br />

}<br />

[MetadataAttribute]<br />

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]<br />

public class SpeedExportAttribute : ExportAttribute<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!