Exercise 2: Using Metadata and Lazy-Loading Modules

During composition of a part, an import will trigger the instantiation of a part (or parts) that expose the necessary exports required for the original requested part. For some applications, delaying this instantiation and preventing the recursive composition down the graph, may be an important factor to consider, since the creation of a long and complex graph of objects can be expensive and unnecessary.

This is the motivation for MEF to support what we call lazy exports including the Lazy generic type, this type allows delay the load process of the objects until the moment it is first called, minimizing the time required to initialize the application.

In this type of scenarios, associating information with the export becomes critical to inform the importer about the capabilities of a specific implementation of a common contract.

In this exercise, we will tackle both problems in a single scenario.

Task 1 – Attaching Metadata to an Export

In some cases, it is necessary to associate information with exports for a variety of reasons. Commonly you use metadata to explain about the capabilities of a specific implementation of a common contract. In this task, you will modify an existing Query implementation to expose some properties as metadata.

  1. Open Microsoft Visual Studio 2010 from Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010.
  2. Open the ContosoAutomotive.sln solution file. By default, this file is located in the folder Source\Ex2\begin(choosing the folder that matches the language of your preference.) Optionally, you can continue working the solution you created in the previous exercise.
  3. You will start adding metadata to the WoodgroveQuery implementation. To do this, open the WoodgroveQuery.cs (C#) or WoodgroveQuery.vb (Visual Basic) file under the ContosoAutomotive.Woodgrove project.
  4. Since you will attach metadata by using attributes, you no longer required the initialization code. Remove the WoodgroveQuery constructor that initializes the Name, Description and ImagePath properties.
  5. To attach metadata to an Export implementation, you decorate the class with the ExportMetadata attribute. In this case, you will attach the same information you removed from the constructor initialization. To do this, decorate the WoodgroveQuery class with the following attributes.

    (Code Snippet – Intro to MEF Lab - Ex2 Task1 Step5 -WoodgroveQueryMetadata CSharp)

    C#

    [Export(typeof(ICarQuery))]
    [ExportMetadata("Name", "Woodgrove Cycles")] [ExportMetadata("Description", "Who doesn't love a Woodgrove? The fastest thing on two wheels!")] [ExportMetadata("ImagePath", "Images/woodgrove.jpg")]FakePre-3e030cc691054de1a367584576f72c4b-04c60b1c482a480b9632fea3a24eb8b0FakePre-7ae1bb82931b4f9aa30a4ab6886c1249-f037cad078404f06a4fa022d47d18707FakePre-7e3045bf2bbd40808eb57aca00729e9a-7ee155657aa445dfb01f3a455e058dd6FakePre-fa19e55e098143399e11e696945774fb-bcfb64d067d04024a85acf8c7fe24ce7FakePre-38c51168176140a7a41ed2586d52f87b-8dd98bd63df447aa89780599a26659d8

    (Code Snippet – Intro to MEF Lab - Ex2 Task1 Step5 - WoodgroveQueryMetadata VB)

    Visual Basic

    <Export(GetType(ICarQuery))>
    <ExportMetadata("Name", "Woodgrove Cycles")> <ExportMetadata("Description", "Who doesn't love a Woodgrove? The fastest thing on two wheels!")> <ExportMetadata("ImagePath", "Images/woodgrove.jpg")>FakePre-eed1d94341514630b80b02803e43ae63-b5fed9e97f8b468a9bc6143576650db0FakePre-efbf74858bd243e79f155391d9ebc064-a55be49a5ac049cda3b345ea6d38be51FakePre-3f445932116e42a49daeeb47ac7ffa92-f302e7a7dc2a49f89156b36183c9e34aFakePre-92851452687e4a46b69ad0f08551fee1-cf3c0a057cf24ca88129f72a02beb0f7FakePre-f0d4959942b74aee805f58e15efa8c3c-52a9979424ac449f9db8e4a903a2dbf3FakePre-396b4ad0eede4878a4027a7d791cb005-910d0549ce8745279b2f7f59c43d0750

    Note:
    You decorate a class with the ExportMetada attribute to include metadata to it. This attribute receives two parameters defining the name and the value of the class’ metadata respectively.

Task 2 – Using a Custom Export Attribute

In order to attach metadata to an export in a more strongly typed fashion than using the ExportMetadata attribute, you can create your own attribute and decorate it with the Metadata attribute. In this task, you will create a custom metadata attribute and derive it from Export attribute, thus creating a custom Export attribute that also specifies metadata.

  1. Create a new QueryMetadata class that will serve to both define an export and attach metadata at the same time. To do this, right click on the ContosoAutomotive.Extensions project and select Add | Class. In the Add New Item dialog, name the class as QueryMetadataAttribute and click OK.

    Figure 8

    Adding QueryMetadataAttribute class (C#)

    Figure 9

    Adding QueryMetadataAttribute class (Visual Basic)

  2. Update the QueryMetadataAttribute class to use the MEF library. To do this, add the following statement at the top of the QueryMetadataAttribute class definition.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step2 - Namespaces CSharp)

    C#

    using System.ComponentModel.Composition; using ContosoAutomotive.Common;

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step2 - Namespaces VB)

    Visual Basic

    Imports System.ComponentModel.Composition Imports ContosoAutomotive.Common

  3. Make the QueryMetadataAttribute class definition public and decorate it with the MetadataAttribute and AttributeUsage attributes. In addition, make the class inherits from the ExportAttribute class. To do this, replace the default class definition with the following code.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step3 - QueryMetadataAttribute CSharp)

    C#

    [MetadataAttribute] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class QueryMetadataAttribute : ExportAttribute { }

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step3 - QueryMetadataAttribute VB)

Visual Basic

<MetadataAttribute(), AttributeUsage(AttributeTargets.Class, AllowMultiple:=False)> Public Class QueryMetadataAttribute Inherits ExportAttribute End Class

Note:
Both attributes, MetadataAttribute and AttributeUsage, are required to be included as decorators of the typed Metadata class.

MetadataAttribute defines that the class can be used to define typed metadata of another class.

AttributeUsage sets where the attribute can be placed. In this exercise, the attribute can decorate a class, and cannot be used more than one time on the same class.

  1. Add the required metadata properties and setup the inherited constructor to export the ICarQuery interface explicitly. To do this, insert the following code inside the QueryMetadataAttribute class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step4 - QueryMetadataImplementation CSharp)

    C#

    [MetadataAttribute]
    FakePre-b266ea9794494f0091e4cf8eda2d8c10-ce78b0d5db54405583ab65442b7a383fFakePre-c16bf977a6fa4dc3a29b2affdbe229ae-febc43e5fadc4c0cbf8c4cf7971690e0FakePre-6dbb6ff5e6274c649c022ef691e5b200-4e6978ce3a9e49cba13d191876722256 public QueryMetadataAttribute() : base(typeof(ICarQuery)) { } public string Name { get; set; } public string Description { get; set; } public string ImagePath { get; set; }FakePre-ef8993f6b63b4f97b19ca65d7f284b36-382eac899c9645e6b6ad6a114489d8efFakePre-923105ef9737453bb8142e7bdded35bd-d70c85073acb49e19a29e92df29999d6

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step4 - QueryMetadataImplementation VB)

    Visual Basic

    <MetadataAttribute(), AttributeUsage(AttributeTargets.Class, AllowMultiple:=False)>
    FakePre-216680b63e14455abad078b255662a2c-de3cde9d49ef40d9a4557af71d273607FakePre-87c5ce452bf445589fdb9636fac718b6-93afec511afb4eada37e97e5b4d4ef37FakePre-356bc710a34b486d8940b0d3ee2d6417-86c70108058749cda520f78f93353e41Public Sub New() MyBase.New(GetType(ICarQuery)) End Sub Public Property Description As String Public Property ImagePath As String Public Property Name As StringFakePre-c3968d9bf6a743cda0a5a85d6bb2ede9-a76b23f640d8440b9c6a52a1bd466420FakePre-c247d587004d421fb8ab08e138925d9a-783f70c3dc3a430d8e17d3bccfaca8f8FakePre-fca3fb1bb2474f6ca5a1cf435ffb0d1d-7c72e903bb5f41c080a8fddf33b9e55eFakePre-f98f4fe544194009bf24968bf513f25e-d697b0e7baf74a3c99e81c85ff3ef4f0

    Note:
    Inheritance from ExportAttribute and calling the ExportAttribute class’ constructor passing the ICarQuery type automatically sets that the contract implemented by the class is the ICarQuery. This allows avoiding specifying it when you decorate the class as you did when you used the ExportAttribute directly.

  2. Now, you can attach metadata and export a contract using the QueryMetadata attribute in your classes removing both the Export decorating attribute and the initialization constructor. To do this, remove the constructor and replace the class definition in the CohoQuery class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step5 - CohoQueryMetadata CSharp)

    C#

    [QueryMetadata(Name = "Coho Auto", Description = "Nothing beats a good price on a Coho. We can't keep these things in stock.", ImagePath = "Images/coho.jpg")]
    public class CohoQuery : CarQueryBase
    FakePre-1db89e74788143e28a90ef4e98a76a44-e8e1892fc97f4c4d8891820982633e33FakePre-867e8a4a9b664a46a2195817b03cfd01-f1f0d6bb58cd4dadb6a6d5c728d716f4FakePre-cea7f6d4a382437d9f3a22229685c196-af5cf6a5477c49049b0965787461a55cFakePre-d4e678aea2894698879d3e7c45f83e8c-624a4c7f49a8404dab9bfd9b59aafa39

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step5 - CohoQueryMetadata VB)

Visual Basic

<QueryMetadata(Name:="Coho Auto", Description:="Nothing beats a good price on a Coho. We can't keep these things in stock.", ImagePath:="Images/coho.jpg")>
Public Class CohoQuery
FakePre-03f07761ec784bef912186f8d1f60ec0-c26e566a192a47ac8796e0d6a5b22ad4FakePre-bcabc2f04c244284ae09e71caa2b24c3-1e773381eaef4e68b0fd94eca6e642afFakePre-8c50669bac1349b69e712415a09e1bfd-905aa528594a4167931800d452cdcaa2FakePre-d17435770aa64004900c3bca498851a5-93832cd042114084865a0381b825671a

  1. You will repeat the same process on the FabrikamQuery class. To do this, remove the constructor and replace the class definition in the FabrikamQuery class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step6 - FabrikamQueryMetadata CSharp)

    C#

    [QueryMetadata(Name = "Fabrikam Motor Company", Description = "Low Mileage, Low Price FMCs that have wonderful resell value.", ImagePath = "Images/fabrikam.jpg")]
    public class FabrikamQuery: CarQueryBase
    FakePre-9eced29f6a784780af488479c948080f-641e25b80ea743f08a74bfee683376c8FakePre-22bae2ba5e434046890e5b24f74a3c42-c0e0a459b69b47679e84ba8e08c95712FakePre-de71908079324810bce2501a9432a47c-10cd0abf609c4d719841c162f2105195FakePre-a85ef2c41a97406b818ec1653a04fb3e-5617c7eaa82d4a1db5f65d291ca51f32

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step6 - FabrikamQueryMetadata VB)

Visual Basic

<QueryMetadata(Name:="Fabrikam Motor Company", Description:="Low Mileage, Low Price FMCs that have wonderful resell value.", ImagePath:="Images/fabrikam.jpg")>
Public Class FabrikamQuery
FakePre-382da89882fc4767b2ef769e3d2957bb-8086a476325f47c8bbec7ad4f8f6bfb5FakePre-794e8c8806e2429ba059a1ea74b9fdd3-eea155342d4d45adb0fe0d7d88e4d1fcFakePre-66ff376ed7c44b8ebb2536a47912dcd7-d97947ceefc24e2a90927caf2c9eefd7FakePre-6d0b813fbf4c4d01abad4bbface7669a-972e85b1683c4f2da3b203340e84c226

  1. You will repeat the same process on the LitwareQuery class. To do this, remove the constructor and replace the class definition in the LitwareQuery class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step7 - LitwareQueryMetadata CSharp)

    C#

    [QueryMetadata(Name = "Litware Limousines", Description = "Grab a Litware. We can make an absolutely steal off these party favorites.", ImagePath = "Images/litware.jpg")]
    public class LitwareQuery: CarQueryBase
    FakePre-6b627fb4e9ae48e186b9897769e2b1e8-9e65dba030834f5c83b9fe26d2d9c755FakePre-534a9d1ae0c045deb8e42e070772ea1e-8e8675bc59f34f6ea75beb3e060dc929FakePre-034edb3d53044beaa0f3f0ec91f1d4f8-7753c349363f48bea7ef9fab16c665bcFakePre-6eeb52a3a8104c85a0780bdae0f456c0-ea726c44f94e454bb2b53f1c4700ebde

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step7 - LitwareQueryMetadata VB)

Visual Basic

<QueryMetadata(Name:="Litware Limousines", Description:="Grab a Litware. We can make an absolutely steal off these party favorites.", ImagePath:="Images/litware.jpg")>
Public Class LitwareQuery
FakePre-8e3ac0016278492fb87534d2f2432ae5-5e57fffc40d54bed81178b36bf203e1dFakePre-719003b7c441459395fa8c98de3c99cd-83447c329e5b4f7181e6cba6b76b6146FakePre-9fc76decf6b848658220897f4e116595-724b9907e59f455b92be8301b0b54e04FakePre-fa671a641b064ddc8ed69becd069eea5-699da8de601240bb81da02e77bf66a71

  1. You will repeat the same process on the TailspinQuery class. To do this, remove the constructor and replace the class definition in the TailspinQuery class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step8 - TailspinQueryMetadata CSharp)

    C#

    [QueryMetadata(Name = "Tailspin Motorsport", Description = "Life in the fast lane. You can't live without the best: Tailspin.", ImagePath = "Images/tailspin.jpg")]
    public class TailspinQuery: CarQueryBase
    FakePre-a7d9ddf7ff1a475786789f17a7056aea-e29effbad1404712a733175d15def4e6FakePre-9f01239591104b1bbde16c14c375a7e7-d0d1c403cdd94542915c325ec03290d0FakePre-3c6f8a11f2d7482bb1ce3e749aeda71f-e36a06f470d0403da5ac471667ddd8dcFakePre-24a7ad5fba5944cc89309067eb88e1a3-f394f756c50342df970520e2f68a9ad9

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step8 - TailspinQueryMetadata VB)

Visual Basic

<QueryMetadata(Name:="Tailspin Motorsport", Description:="Life in the fast lane. You can't live without the best: Tailspin.", ImagePath:="Images/tailspin.jpg")>
Public Class TailspinQuery
FakePre-64363efecc554096a2ce6567b991a729-e0ade689ef32436f96df5682bcb267e8FakePre-ae5a811b88d945d48e044c174412cc19-4a192030981147f6962b2549105db671FakePre-f9fb309597cc4fdeafc34d8f96a8156d-f843c4d49fa144829c367805bc536d16FakePre-64dfa44845044ca88bb48b62865f165a-9ee4b604c5324700871344cb172e12d4

  1. You will repeat the same process on the WingtipQuery class. To do this, remove the constructor and replace the class definition in the WingtipQuery class.

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step9 - WingtipQueryMetadata CSharp)

    C#

    [QueryMetadata(Name = "Wingtip Automobiles", Description = "Ah, the Wingtip. The joy of millionaires. But can we find a low mileage one?", ImagePath = "Images/wingtip.jpg")]
    public class WingtipQuery: CarQueryBase
    FakePre-bb6f199679d0418bb5b282389d827af8-61a21dffeb3542f49f368dccbd1d6185FakePre-79b2542f5cf740b490ce8d767e48f895-191c517e1d6d4e088ffbba1f57daa29fFakePre-d67e8148e13845baacb8279cba3f6046-f38449fc45f3437a9c1166323c90f5fbFakePre-1053e45de8724e098c0acd7ce12776bb-dbed4e96261e4d5f8ad266a2e755a9a0

    (Code Snippet – Intro to MEF Lab - Ex2 Task2 Step9 - WingtipQueryMetadata VB)

Visual Basic

<QueryMetadata(Name:="Wingtip Automobiles", Description:="Ah, the Wingtip. The joy of millionaires. But can we find a low mileage one?", ImagePath:="Images/wingtip.jpg")>
Public Class WingtipQuery
FakePre-0bed7557a0d44580836f2d2501a3e143-6aa88ffe3bb34b5ea48f85f7f1d3c95aFakePre-d6d048b0844f4162aa82a124c21aabd3-07d9076bfa7944c89ad891545683237eFakePre-3c0fcd77e4f24c7b86fe7d0b60bef0e5-b1fe68a983f64227bb9973914e1a9ad7FakePre-9f95500b580148499ff3056a34e76d3d-9de55295be3f464db9b446383b482bd0

Task 3 – Importing Metadata

In this task, you will modify the way import occurs to let importers access the metadata attached to the exports.

  1. To access metadata in a strongly typed fashion create a metadata view by defining an interface with matching read only properties (names and types). To do this, right click on the ContosoAutomotive.Common project and select Add | New Item. In the Add New Item dialog select Interface type and name it IQueryMetadata.

    Figure 10

    Adding IQueryMetadata interface (C#)

    Figure 11

    Adding IQueryMetadata interface (Visual Basic)

  2. Make the interface public and add the desired metadata properties as read only. To do this, replace the default interface implementation with the following code.

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step2 - IQueryMetadata CSharp)

    C#

    public interface IQueryMetadata { string Name { get; } string Description { get; } string ImagePath { get; } }

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step2 - IQueryMetadata VB)

    Visual Basic

    Public Interface IQueryMetadata ReadOnly Property Name As String ReadOnly Property Description As String ReadOnly Property ImagePath As String End Interface

  3. Since you are no longer using the Name, Description and ImagePath properties you can remove them from the CarQueryBase class. To do this, open the CarQueryBase.cs (C#) or CarQueryBase.vb (Visual Basic) and remove the Name, Description and ImagePath properties and their associated member fields.
  4. Modify the main application to retrieve the query information from metadata instead of retrieving it from the query instance. To do this, open the CashMaker class by right clicking on the CashMaker.xaml file under the ContosoAutomotive project and select View Code in the contextual menu.
  5. Now you can start importing using the type System.Lazy<T, TMetadata> where T is the contract type and TMetadata is the interface you have created. To do this, replace the CarQueries field definition inside the CashMaker class with the following code.

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step5 – CarQueries Property CSharp)

    C#

    [ImportMany(AllowRecomposition = true)] public ObservableCollection<Lazy<ICarQuery, IQueryMetadata>> CarQueries { get; set; }

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step5 – CarQueries Property VB)

    Visual Basic

    <ImportMany(AllowRecomposition:=True)> Public Property CarQueries As ObservableCollection(Of Lazy(Of ICarQuery, IQueryMetadata))

    Note:
    As it was explained, Lazy type allows delaying the object instantiation until it is used, specifically, the object will be created when the Value property of the Lazy object will be called.

    You are declaring the Lazy type using the contract type and the metadata type. The last one is not required but you are defining it because you want to access the metadata information avoiding the object instantiation.

  6. Since you have modified the bound collection, you should adapt the SelectionChange event handler to deal with a Lazy Query object. To do this, replace the bolded lines of code below to use a proper approach to run queries.

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step6 – CommandList Event CSharp)

    C#

    private void commandList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    FakePre-c564d71182fd4263a0e9f05609602d1c-b084ccd6d5964a4aa1ca6d25074f6241FakePre-078a57f7c0e44d588037f5bfd2b8edee-7e04e4f464214472b00c79bd1dd44126FakePre-58601ad6e377478ca7cf51917024e083-52c9bd05a3f9450aa03928fd1ca6377aFakePre-ebf0247c524b44a9a1f4f16176a5a0e9-bc70f87185bf4f36a1eadabab4192f2dFakePre-3a45efd74e68424ab34b2a05452e1c3e-53417775af2c4dde98010e43dea12efaFakePre-d3d770742eb2433daca9a5fe8217be57-fe4692cc797a497ba99d154225e3bfc4FakePre-65971a32580942bc93383c6345603821-9dac881142a5483aad6b62e1ec3aea6fFakePre-0507d5e56f654c489475c27e77605265-df66e964043e4ef3bf3720f3a6720a6d var lazyQuery = e.AddedItems[0] as Lazy<ICarQuery, IQueryMetadata>; if (lazyQuery != null) { lazyQuery.Value.Run(this.cars, true); }FakePre-b8398e9da8e24c32b7b182826409399a-2313a10112d5449492a28f50827b5046FakePre-0218df3997334d43aa7fd69834dce1d3-5a84c4ca636649988fe7aaf1d800f3bdFakePre-469865e91aa74887a37661394101046b-f3c04b2ce89640389ba21e340e3275ebFakePre-3d6838b7d5a2488ea9f2547ee3703757-d8cce29c53a14ac7b4c17c0314f8ad2eFakePre-5d28a0bb58b543e89333227ba1dd4c7a-2373a3fab2984c038b496c40f9271c4dFakePre-7d6b44b34a114523a277e9cb48f10900-e1ba0b614eb1422d9035a230b511538dFakePre-06b9151931f545e9a42e86431bb70ecf-027e6336b9784d75a84a1f79c3d67ad7FakePre-bb05fd7c5c944a53abaee0833cce3448-5acc517be68c42b6b030446ce2d06c61FakePre-db7e65b31dab4f82a204870b720b30be-0032287e932f4468a1bdc21ae0b61a9aFakePre-259cde5671ad4918948faf7e8ba230d6-69de835a5a7a4c9889190219891efe16

    (Code Snippet – Intro to MEF Lab - Ex2 Task3 Step6 – CommandList Event VB)

    Visual Basic

    Private Sub commandList_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    FakePre-e03ae4469171424aa9f3c530baa3af45-066a113675b74eb180d608f1417f7e2dFakePre-936151e374b643a485a503254c4ce0fb-9f640fb5492b4069b5085ff1ef9639a8FakePre-5c712368c372422385cab6578eb8bdac-80cf3909ecbd41549029f0fa23d3c0b6FakePre-11b8904695984236b2df91aafa5243f3-fab2ab5984f341bc8e46269eee7886e1 Dim lazyQuery = TryCast(e.AddedItems(0), Lazy(Of ICarQuery, IQueryMetadata)) If (lazyQuery IsNot Nothing) Then lazyQuery.Value.Run(Me.cars, True) End IfFakePre-59c3e4c49a7a4bd389a3afdbc651d110-96e6c42414ab4c92a260c48793614ea5FakePre-9009e759e6094a5e8bd72219e48d8165-737734ee632e4309814c3b4458999e45FakePre-2006f15db5f446949db5d112fab4e976-1559163d11ff44738291353b8c111e97FakePre-de37832f591248b0ab10401f8ed0249a-59843af6968a49748ed9a0d1c160bcd0FakePre-00fff6a829bd45cdad3e1f30203868c0-c8fe8b8258a8466b89b5cb0c92cc79bcFakePre-6772a98f7d2c4619b07c3c255b64afc6-4bab417d9dc2482abc38a3820c5e7b41FakePre-af4a4707cb874556aad9de808db5953d-a4d4e7a8aa6140eb91c3e539d69c3325FakePre-5c6e886219864bd980e190db6d2bf467-8c3842093766456196f794a2e64f2de8FakePre-de97b0cae73f45ca8d5e46a9100e83cf-4067e8247a1a4c138ce7be96bab2cf97FakePre-4c911313b3f24f9da6f0814d693617b5-1f44597a11584fba9c536b957d0b5b7f

  7. Modify the UI XAML code as well to adapt the UI to the new lazy model. To do this, right click on the CashMaker.xaml file and select View Designer in the contextual menu. For simplicity, expand on the XAML tab to show only the markup code.
  8. Scroll down to the <DataTemplate> element with the QueryItem key and adapt the Path property of the Binding objects to retrieve the Name, Description and ImagePath from the Metadata property of the Lazy objects. To do this, replace the highlighted bolded lines of markup code as shown below.

    XAML

    <DataTemplate x:Key="QueryItem">
    FakePre-0a0aadf79de048b9b16c1caedf536750-09fa77ea435e478e83b1100278fc6488FakePre-717e22b5526c4e678eb74bb00e696921-4a7b47f8b1d447819d07889e2f15adeaFakePre-30102700d97f41f8a69f0ee53b47b38c-009bf55b2b1d4cdcabdbb6959d95ceb7FakePre-686515a788284fd9aaf82ad46bd24fcb-5be8729df4174adb8259393fc1ff615cFakePre-d984ec1eb59843e382e129f341b79bf3-cc21c497353e465db13e92832603b599FakePre-d04c7bd079d74f2490376d8dc0b4e1fe-62024a663c354722a2e36559babc4e75FakePre-9b18adaa4d4d445fae751aaeefe79232-a513251f75dc401bbeae5908bf1adf2bFakePre-2b8dbf49e8fc4f33a849eaae9edeb651-1da8020a1be44063bbdb8ce021d437ddFakePre-7f2afc137e584d329e6afe8d01a98d4d-05206932237e4587a61f9ef2eafbea15FakePre-f69615f6772244c4bb43b569a923446d-98a4dbe9a41c4f658a027782894b8233FakePre-651a1903d21d4609ae95f48a8b555fb9-5bcc5f3794ba41418419e5b6bc547d9cFakePre-9948dc1d293a4076b2b66d17c6369f54-9362d2f863cb4820937175518016fa83FakePre-5f7da792ed8346598a2470b4a624d111-ceae13dbca084694864a0abf4ff12424FakePre-721103f456254cf1b3ab23447b7cef68-8675665ab9644b858cbe6f5cf59b25cbFakePre-24d088df36fb4fbd9dc99a9cae6c7c6f-88dfc1c2f5024d289e63498fd7dc640fFakePre-4262e4c2052f473997e3faf7eed82d13-c698f02f16b04f0d8cff94c1838534beFakePre-45232005120e4d01b67f0d8a499f4237-3825ce7f251e42ef932552fd4feafb96FakePre-9eb48beeb4f54738bd162d0864853323-d80df146186141019aff1eba7fbc5affFakePre-5489543e9645421c8d281ee4c19f4787-44a9a8711a4f4acb920100d8ac48abecFakePre-e58292978a524c31b78846bb188795b1-5fac5c6e59274bd78aa98d17aadc93e0FakePre-e90df2010c7141029bdff599b81d468b-1f89073062b54c4e946ea605f955dc64

    Note:
    The Lazy type expose a property called Metadata, which is the metadata type defined on the Lazy type declaration (in this case, IQueryMetadata). This property is used in the XAML above to access the metadata information of the different query items instead of use the object properties as it was implemented in the previous exercise.

  9. Scroll down to the <ContentControl> element at the bottom of the file and adapt the Path property of the Binding object to retrieve the Results object from the Value instance of the Lazy objects. To do this, replace the bolded lines of markup code as shown below.

    XAML

    <ContentControl Width="700" Margin="1 1 5 1" VerticalAlignment="Top">
    FakePre-33e14ca5155c4bdfa6f1979e366105ea-fbee87b6ef704e598f7014236ad70a51FakePre-458d04a58c8e4585b0cefa1ab806eda7-355a29d54e5a4206ad27ff6dbd453059FakePre-ecf824785b874257bafdb9b01749ecad-67110efb80714d90852be5ac22442617FakePre-3216f18772ca4521b357673e5091c21a-669a5413ef0c493d9a0095f4d6645045

    Note:
    As it was explained for the Lazy’s Metadata property. The Value property matches the contract type on the lazy type definition (in this case, ICarQuery) and allows accessing the different object’s properties and methods.

Next Step

Exercise 2: Verification