44
Page | 1 Hands-On Lab Building Windows Azure Apps with Caching service Lab version: 2.0.0 Last updated: 11/16/2010 CONTENTS OVERVIEW ................................................................................................................................................... 3

Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 1

Hands-On Lab

Building Windows Azure Apps with Caching service

Lab version: 2.0.0

Last updated: 11/16/2010

CONTENTS

OVERVIEW ................................................................................................................................................... 3

Page 2: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 2

GETTING STARTED: PROVISIONING THE SERVICE .............................................................................. 5 Task 1 – Provisioning the Service Bus Namespace ............................................................................... 5

EXERCISE 1: USING THE WINDOWS AZURE APPFABRIC CACHING FOR SESSION STATE ........... 9 Task 1 – Running the Azure Store Sample Site in the Development Fabric........................................ 10

Task 2 – Configuring Session State Using Windows Azure AppFabric Caching ................................... 14

Task 3 – Verification ............................................................................................................................ 17

EXERCISE 2: CACHING DATA WITH THE WINDOWS AZURE APPFABRIC CACHING ..................... 18 Task 1 – Caching Data Retrieved from the SQL Azure Repository ...................................................... 18

Task 2 – Measuring the Data Access Latency ..................................................................................... 22

Task 3 – Enabling the Local Cache....................................................................................................... 27

EXERCISE 3: CREATING A REUSABLE AND EXTENSIBLE CACHING LAYER .................................. 33 Task 1 – Implementing a Caching Data Source Base Class ................................................................. 34

Task 2 – Building a Caching Product Catalog Repository .................................................................... 37

Task 3 – Creating a Data Source Factory Class .................................................................................... 39

Task 4 – Configuring the Application for Caching ............................................................................... 42

SUMMARY .................................................................................................................................................. 44

Page 3: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 3

Overview

The Windows Azure AppFabric Caching service provides a distributed, in-memory cache for your

applications. In this lab, learn how to use the Caching service for both your ASP.NET session state and

to cache data from your data-tier. You will see how the Caching service provides your application with a

cache that provides low latency and high throughput without having to configure, deploy, or manage

the service.

Objectives

In this hands-on lab, you will learn how to:

Easily and quickly provision your cache through the portal

Use the caching service for your ASP.NET session state

Cache reference data from SQL Azure in the caching service

Create a reusable and extensible caching layer for your applications

During this lab, you will explore how to use these features in a simple ASP.NET MVC application.

Prerequisites

The following is required to complete this hands-on lab:

Microsoft .NET Framework 4.0

Microsoft IIS 7

Microsoft Visual Studio 2010

Windows Azure Tools for Microsoft Visual Studio 1.2 (June 2010)

Windows Azure AppFabric SDK v2.0

Setup

For convenience, much of the code used in this hands-on lab is available as Visual Studio code snippets.

To check the prerequisites of the lab and install the code snippets:

1. Open a Windows Explorer window and browse to the lab’s Source\Setup folder.

2. Double-click the Dependencies.dep file in this folder to launch the Dependency Checker tool

and install any missing prerequisites and the Visual Studio code snippets.

Page 4: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 4

3. If the User Account Control dialog is shown, confirm the action to proceed.

Note: This process may require elevation. The .dep extension is associated with the Dependency

Checker tool during its installation. For additional information about the setup procedure and how to

install the Dependency Checker tool, refer to the Setup.docx document in the Assets folder of the

training kit.

Note: This lab requires a SQL Azure database to start. To build the Northwind2 database automatically,

the Dependency Checker tool will prompt to you with your SQL Azure account information. Remember

to update the NorthwingEntities connection string in the application’s configuration file to point to

your database for each solution.

Note: Remember to configure the firewall setting your SQL Azure account to allow you to specify a list

of IP addresses that can access your SQL Azure Server. The firewall will deny all connections by default,

so be sure to configure your allow list so you can connect to the database. Changes to your firewall

settings can take a few moments to become effective. For additional information on how to prepare

your SQL Azure account, refer to the exercise 1 of the Introduction to SQL Azure lab in the training kit.

Figure 1

SQL Azure database setup

Using the Code Snippets

Throughout the lab document, you will be instructed to insert code blocks. For your convenience, most

of that code is provided as Visual Studio Code Snippets, which you can use from within Visual Studio

2010 to avoid having to add it manually.

Page 5: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 5

If you are not familiar with the Visual Studio Code Snippets, and want to learn how to use them, you can

refer to the Setup.docx document in the Assets folder of the training kit, which contains a section

describing how to use them.

Exercises

This hands-on lab includes the following exercises:

1. Using the Windows Azure AppFabric Caching for Session State

2. Caching Data with the Windows Azure AppFabric Caching

3. Creating a Reusable and Extensible Caching Layer

Estimated time to complete this lab: 60 minutes.

Note: When you first start Visual Studio, you must select one of the predefined settings collections.

Every predefined collection is designed to match a particular development style and determines

window layouts, editor behavior, IntelliSense code snippets, and dialog box options. The procedures in

this lab describe the actions necessary to accomplish a given task in Visual Studio when using the

General Development Settings collection. If you choose a different settings collection for your

development environment, there may be differences in these procedures that you need to take into

account.

Getting Started: Provisioning the Service

To complete the exercises in this lab, you require an AppFabric Project. Once you have created a project,

you can use it for all the AppFabric labs as well as your own projects.

Task 1 – Provisioning the Service Bus Namespace

In this task, you create a new project and create a service namespace to use the Windows Azure

AppFabric Caching.

1. Navigate to the Windows Azure platform AppFabric portal and, if necessary, sign in using your

Windows Live ID credentials.

2. If this is the first time you access the AppFabric site, you need to create a new project.

Page 6: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 6

Figure 2

AppFabric projects page

3. Enter a Project Name, such as your company name or your own name, and then click OK.

Figure 3

Creating a new Azure AppFabric project

4. In My Projects, click the newly created project to view its summary page.

Figure 4

Selecting a project to manage

5. Now, create a service namespace for this project. To add a service namespace, click the Project

Name link for your new project to open its summary page and then click Add Service

Namespace.

Page 7: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 7

Figure 5

AppFabric project summary page

Note: A service namespace defines a boundary for each application exposed through the

Service Bus, allowing an application to uniquely address the AppFabric service endpoints.

6. Enter a name for your Service Namespace and then click Validate Name to ensure its

availability. Service names must be globally unique as they are hosted in the cloud and

accessible by whomever you decide to grant access. If the service is unavailable, you will need

to pick a different name. Once you have determined that the chosen namespace is valid and

available, click Create.

Figure 6

Creating a new service namespace

Page 8: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 8

7. Locate the new entry in the list of configured service namespaces and then wait for its Status

column to show the namespace as Active.

8. After the namespace is provisioned, click its Cache link to display the Cache Settings page.

Figure 7

Project summary page listing available service namespaces

9. In the Cache Settings page, you can review the different shown values. Locate the Cache section

and review the value shown for the Service URL, the Service Port, Authentication and Token.

These values will be used later on this lab.

Figure 8

Service namespace cache settings

Page 9: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 9

10. Locate Application Integration section, which contains the configuration required to leverage

Windows Azure AppFabric Caching. Do not close the browser, since you will have to come back

to this page later in the lab.

Figure 9

Copying xml from Application Integration section

Exercise 1: Using the Windows Azure

AppFabric Caching for Session State

In this exercise, you explore the use of the session state provider for Windows Azure AppFabric Caching

as the mechanism for out-of-process storage of session state data. For this purpose, you will use the

Azure Store—a sample shopping cart application implemented with ASP.NET MVC. You will run this

Page 10: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 10

application in the development fabric and then modify it to take advantage of the Windows Azure

AppFabric Caching as the back-end store for the ASP.NET session state. You start with a begin solution

and explore the sample using the default ASP.NET in-proc session state provider. Next, you add

references to the Windows Azure AppFabric Caching assemblies and configure the session state provider

to store the contents of the shopping cart in the distributed cache cluster provided by Window Azure

AppFabric.

Task 1 – Running the Azure Store Sample Site in the Development Fabric

In this task, you will run the Azure Store application in the development fabric using the default session

state provider; you will change that provider to take advantage of the Caching service later on.

1. Start Microsoft Visual Studio 2010 as an administrator.

2. Open the Begin solution located at Ex1-AppFabricCacheSessionState inside the Source folder of

the lab.

Important: Before you execute the solution, make sure that the start-up project is set. For

MVC projects, the start page must be left blank.

To set the start-up project, in Solution Explorer, right-click the AzureStoreService project and

select Set as StartUp Project.

To set the start page, in Solution Explorer, right-click the MVCAzureStore project and select

Properties. In the Properties window, select the Web tab and in the Start Action, select

Specific Page. Leave the value of this field blank.

3. In the Web.config file, update the NorthwindEntities connection string to point to your

database. Replace [YOUR-SQL-AZURE-SERVER-ADDRESS], [SQL-AZURE-USERNAME], and [SQL-

AZURE-PASSWORD] with the SQL Azure database server name, Administrator Username and

Administrator password that you registered at the portal and used for creating the database

during setup.

Note: Make sure that you follow the instructions of the setup section to create a copy of the

Northwind2 database in your own SQL Azure account and configure your SQL Azure firewall

settings.

4. Press F5 to build and run the application in the development fabric.

5. Explore the main page of the application, the Products page, which displays a list products

obtained from a SQL Azure database.

Page 11: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 11

Figure 10

Azure Store products page

6. Select a product from the list and click Add item to cart. You may repeat the process to store

additional items in the shopping cart.

7. Click the Checkout link to view the contents of the cart. Verify that the items you selected

appear on the list. These items are stored in the current session.

Page 12: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 12

Figure 11

Checkout page showing the contents of the shopping cart

8. Do not close the browser window or navigate away from the checkout page.

9. In the task bar, right-click the development fabric icon and select Show Development Fabric UI.

10. In the Development Fabric, right-click the AzureStoreService node and choose Suspend.

Page 13: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 13

Figure 12

Suspending the service role instance

11. Wait until the service stops as indicated by the instance icon turning red. Now, restart the

service instance once again. To do this, right-click the AzureStoreService node and choose Run,

then wait for the service to start.

12. Switch back to the browser window showing the checkout page and click Refresh. Notice that

the order now appears empty.

Note: The application is currently using in-proc session state, which maintains the session state

in-memory. When you stop the service instance, it discards all session state including the

contents of the shopping cart. In the following task, you will configure the application to store

session state using Windows Azure AppFabric Caching as the storage mechanism, which allows

the application to maintain the session state in the presence of restarts and across multiple

role instances hosting the application.

13. Close the browser window to stop the application.

Page 14: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 14

Task 2 – Configuring Session State Using Windows Azure AppFabric Caching

In this task, you will change the Session State provider to take advantage of the Windows Azure

AppFabric Cache as the storage mechanism. This requires adding the appropriate assemblies to the

MVCAzureStore project and then updating the corresponding configuration in the Web.config file.

1. Add a reference to the Microsoft.ApplicationServer.Caching.Client,

Microsoft.ApplicationServer.Caching.Core, and Microsoft.Web.DistributedCache assemblies.

In Solution Explorer, right-click the MVCAzureStore project, select Add Reference, click the

Browse tab, select the assemblies from the %ProgramFiles%\Windows Azure AppFabric

SDK\V2.0\Assemblies\Cache folder, and click OK.

2. Make sure to include these assemblies as part of the service package. To do this, right-click the

Microsoft.ApplicationServer.Caching.Client assembly and select Properties. In the Project

Properties window, verify that the value of the Copy Local setting is set to True. Do the same

for the other assemblies added in the previous step.

Note: In general, you need to set Copy Local = True for any assembly that is not installed by

default in the Windows Azure VMs to ensure that it is deployed with your application.

3. Open the Web.config file located in the root folder of the MVCAzureStore project.

4. Go back to the browser you left open when creating the service namespace, and locate

Application Integration section. Copy the configSections tag.

Figure 13

Copying configSections

5. Go back to Visual Studio 2010, and paste the section inside the configuration tag. Make sure

that this element is the first element inside the configuration tag.

XML

<configuration>

<configSections>

Page 15: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 15

<section name="dataCacheClient"

type="Microsoft.ApplicationServer.Caching.DataCacheClientSection,

Microsoft.ApplicationServer.Caching.Core"

allowLocation="true"

allowDefinition="Everywhere"/>

</configSections>

<connectionStrings>

...

6. Go back to the browser once more, and copy the dataCacheClient configuration.

Figure 14

Copying dataCacheClient

7. Go back to Visual Studio 2010 and paste the configuration you have copied, under the closing

configSections tag, as shown in the image below.

XML

Page 16: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 16

...

</configSections>

<dataCacheClient deployment="Simple">

<hosts>

<host name="[SERVICE-HOST-NAME]" cachePort="22233"/>

</hosts>

<securityProperties mode="Message">

<messageSecurity authorizationInfo="[AUTHORIZATION_INFO]" />

</securityProperties>

</dataCacheClient>

<connectionStrings>

...

8. The last setting you need to configure is the sessionState provider, to do so, go back to the

browser and copy sessionState element.

Figure 15

Copying sessionState

Page 17: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 17

9. Go back to Visual Studio 2010 and paste the element you copied inside the system.web

configuration section.

XML

...

<system.web>

<sessionState mode="Custom"

customProvider="AppFabricCacheSessionStoreProvider">

<providers>

<!-- specify the named cache for session data -->

<add name="AppFabricCacheSessionStoreProvider"

type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider

, Microsoft.Web.DistributedCache"

cacheName="default"

applicationName="AzureStore"

useBlobMode="false" />

</providers>

</sessionState>

<compilation debug="true" targetFramework="4.0">

...

Note: The DistributedCacheSessionStateStoreProvider session state provider enables out-of-

process storage of session state data using Windows Azure AppFabric Cache as the storage

mechanism.

10. Press CTRL + S to save your changes to the Web.config file.

Task 3 – Verification

1. Press F5 to build and run the application.

Wait for the browser to launch and show the Products page. Select one product from the list

and click Add item to cart. Repeat the process to store additional items in the cart.

2. Click the Check Out link to view the contents of the shopping cart. Verify that the items you

selected appear on the list.

3. Do not close the browser window or navigate away from the checkout page.

Page 18: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 18

4. In the task bar, right-click the development fabric icon and select Show Development Fabric UI.

5. In the Development Fabric, right-click the AzureStoreService node and choose Suspend. Wait

until the service stops as indicated by the instance icon turning red.

6. Now, restart the service instance once again. To do this, right-click the AzureStoreService node

and choose Run, then wait for the service to start.

7. Switch back to the browser window showing the checkout page and click Refresh. Notice that

the order is intact. This confirms that with the Windows Azure AppFabric Caching provider, the

session state is stored outside the role instance and can persist through application restarts.

Note: You should infer from the verification that for an application hosted in multiple servers

or Windows Azure role instances where a load balancer distributes requests to the application,

clients will continue to have access to their session data regardless of which instance responds

to the request.

8. Close the browser window to stop the application.

Exercise 2: Caching Data with the

Windows Azure AppFabric Caching

This exercise shows you how to use the Windows Azure AppFabric Caching to cache results from queries

to SQL Azure. You continue with a solution which is based on the one used for the previous exercise—

the only difference is in the home page that has been updated to show the elapsed time to retrieve the

list of products in the catalog and now has a link to enable or disable the use of the cache.

During the exercise, you update the data access code to use a trivial implementation of caching that

uses the canonical pattern where the code checks the cache first to retrieve the results of a query and, if

these are not available, executes the query against the database and then caches the results.

Task 1 – Caching Data Retrieved from the SQL Azure Repository

To make use of the Caching service, you first need to create a DataCacheFactory object. This object

determines the cache cluster connection information, which is set programmatically or by reading

settings from the configuration file. Typically, you create an instance of the factory class and use it for

the lifetime of the application. To store data in the cache, you request a DataCache instance from the

DataCacheFactory and then use it to add or retrieve items from the cache.

Page 19: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 19

In this task, you update the data access code to cache the result of queries to SQL Azure using the

Windows Azure AppFabric Caching.

1. Start Microsoft Visual Studio 2010 as an administrator.

2. Open the Begin solution located at Ex2-CachingDataWithAppFabric inside the Source folder of

the lab.

Important: Before you execute the solution, make sure that the start-up project is set. For

MVC projects, the start page must be left blank.

To set the startup project, in Solution Explorer, right-click the AzureStoreService project and

then select Set as StartUp Project.

To set the start page, in Solution Explorer, right-click the MVCAzureStore project and select

Properties. In the Properties window, select the Web tab and in the Start Action, select

Specific Page. Leave the value of this field blank.

3. In the Web.config file, update the NorthwindEntities connection string to point to your

database. Replace [YOUR-SQL-AZURE-SERVER-ADDRESS], [SQL-AZURE-USERNAME], and [SQL-

AZURE-PASSWORD] with the SQL Azure database server name, Administrator Username and

Administrator password that you registered at the portal and used for creating the database

during setup.

Note: Make sure that you follow the instructions of the setup section to create a copy of the

Northwind2 database in your own SQL Azure account and configure your SQL Azure firewall

settings.

4. Open the ProductsRepository.cs file in the Services folder of the MVCAzureStore project.

5. Add a namespace directive for Microsoft.ApplicationServer.Caching.

C#

using System;

using System.Collections.Generic;

using System.Linq;

using MVCAzureStore.Models;

using Microsoft.ApplicationServer.Caching;

...

6. In the ProductsRepository class, add the following code to define a constructor and declare a

static member variable for a DataCacheFactory object instance, in addition to a boolean

instance variable to control the use of the cache.

(Code Snippet – BuildingAppsWithCachingService-Ex2- ProductsRepository constructor-CS)

Page 20: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 20

C#

public class ProductsRepository : IProductRepository

{

private static DataCacheFactory CacheFactory = new DataCacheFactory();

private bool enableCache = false;

public ProductsRepository(bool enableCache)

{

this.enableCache = enableCache;

}

public List<string> GetProducts()

{

...

}

}

Note: The DataCacheFactory member is declared as static and is used throughout the lifetime

of the application.

7. Locate the GetProducts method and insert the following (highlighted) code immediately after

the line that declares the products local variable.

(Code Snippet – BuildingAppsWithCachingService-Ex2- GetProducts read cache-CS)

C#

public class ProductsRepository : IProductRepository

{

...

public List<string> GetProducts()

{

List<string> products = null;

DataCache dataCache = null;

if (enableCache)

{

try

{

dataCache = CacheFactory.GetDefaultCache();

products = dataCache.Get("products") as List<string>;

if (products != null)

{

products[0] = "(from cache)";

return products;

}

Page 21: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 21

}

catch (DataCacheException ex)

{

if (ex.ErrorCode != DataCacheErrorCode.RetryLater)

{

throw;

}

// ignore temporary failures

}

}

NorthwindEntities context = new NorthwindEntities();

var query = from product in context.Products

select product.ProductName;

products = query.ToList();

return products;

}

}

Note: The inserted code uses the DataCacheFactory object to return an instance of the default

cache object and then attempts to retrieve an item from this cache using a key with the value

“products”. If the cache contains an object with the requested key, it sets the text of the first

entry to indicate that the list was retrieved from the cache and then returns it. The code treats

temporary failures from the Caching service as a cache miss so that it can retrieve the item

from its data source instead.

8. Next, add the following (highlighted) code block to the GetProducts method, immediately

before the line that returns the products list at the end of the method.

(Code Snippet – BuildingAppsWithCachingService-Ex2- GetProducts write cache-CS)

C#

public class ProductsRepository : IProductRepository

{

...

public List<string> GetProducts()

{

List<string> products = null;

DataCache dataCache = null;

if (enableCache)

{

...

}

Page 22: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 22

NorthwindEntities context = new NorthwindEntities();

var query = from product in context.Products

select product.ProductName;

products = query.ToList();

products.Insert(0, "(from data source)");

if (enableCache && dataCache != null)

{

dataCache.Add("products", products, TimeSpan.FromSeconds(30));

}

return products;

}

}

Note: The inserted code stores the result of the query against the data source into the cache

and sets its expiration policy to purge the item from the cache after 30 seconds.

Task 2 – Measuring the Data Access Latency

In this task, you update the application to allow control of the use of the cache from the UI and to

display the time required to retrieve catalog data, allowing you to compare the latency of retrieving data

from the cache against the time required to access the data source.

1. Open the HomeController.cs file in the Controllers folder and find the Index action. Locate the

lines that instantiate a new ProductsRepository and call its GetProducts method, and replace

them with the highlighted code, as shown below.

(Code Snippet – BuildingAppsWithCachingService-Ex2- GetProducts latency-CS)

C#

public class HomeController : Controller

{

...

public ActionResult Index()

{

Services.IProductRepository productRepository =

new Services.ProductsRepository();

var products = productRepository.GetProducts();

bool enableCache = (bool)this.Session["EnableCache"];

// retrieve product catalog from repository and measure the elapsed time

Services.IProductRepository productRepository =

Page 23: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 23

new Services.ProductsRepository(enableCache);

Stopwatch stopWatch = new Stopwatch();

stopWatch.Start();

var products = productRepository.GetProducts();

stopWatch.Stop();

// add all products currently not in session

var itemsInSession = this.Session["Cart"] as List<string> ?? new

List<string>();

var filteredProducts = products.Where(item =>

!itemsInSession.Contains(item));

IndexViewModel model = new IndexViewModel()

{

Products = filteredProducts

};

return View(model);

}

...

}

2. In the same method, locate the code that creates a new IndexViewModel instance and replace

its initialization with the following (highlighted) code block.

(Code Snippet – BuildingAppsWithCachingService-Ex2-IndexViewModel initialization-CS)

C#

public class HomeController : Controller

{

...

public ActionResult Index()

{

bool enableCache = (bool)this.Session["EnableCache"];

// retrieve product catalog from repository and measure the elapsed time

Services.IProductRepository productRepository =

new Services.ProductsRepository(enableCache);

Stopwatch stopWatch = new Stopwatch();

stopWatch.Start();

var products = productRepository.GetProducts();

stopWatch.Stop();

// add all products currently not in session

var itemsInSession = this.Session["Cart"] as List<string> ?? new

List<string>();

var filteredProducts = products.Where(item =>

!itemsInSession.Contains(item));

Page 24: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 24

IndexViewModel model = new IndexViewModel()

{

Products = filteredProducts,

ElapsedTime = stopWatch.ElapsedMilliseconds,

IsCacheEnabled = enableCache,

ObjectId = products.GetHashCode().ToString()

};

return View(model);

}

...

}

Note: The elements added to the view model provide the time taken to load the product

catalog from the repository, a flag to indicate whether the cache is enabled, and an identifier

for the catalog object returned by the call to GetProducts. The view displays the object ID to

allow you to determine whether the instance returned by the call to the repository has

changed. This feature will be used later in the exercise, when you enable the local cache.

3. Add a new action method to the HomeController to enable or disable the cache from the UI of

the application.

(Code Snippet – BuildingAppsWithCachingService-Ex2-EnableCache method-CS)

C#

public class HomeController : Controller

{

...

public ActionResult EnableCache(bool enabled)

{

this.Session["EnableCache"] = !((bool)this.Session["EnableCache"]);

return RedirectToAction("Index");

}

}

4. Open the Web.config file and locate the dataCacheClient section. Replace the [SERVICE-HOST-

NAME] placeholder with the name of the host for the Caching service endpoint that you

provisioned earlier. For example, for a Service URL such as http://your-

namespace.cache.appfabriclabs.com/, use the value your-namespace.cache.appfabriclabs.com.

Replace the [AUTHORIZATION_INFO] placeholder with the authentication token that you

copied from the Cache Settings page.

Page 25: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 25

5. Press F5 to build and launch the application in the development fabric.

Note: Ideally, you should test the code in Windows Azure. When you execute the application

in the development fabric, consider that accessing the SQL Azure data source and the

Windows AppFabric Caching both require executing requests to resources located outside the

bounds of your own network. Depending on your geographic location, both requests may

exhibit a relatively high latency, which may overshadow the difference between the cached

and non-cached scenarios. Once you deploy the application to Windows Azure, it is co-located

in the same data center as the Caching service, SQL Azure, the latency is much lower, and the

results should be more significant.

6. When you start the application, the cache is initially disabled. Refresh the page and notice the

elapsed time displayed at the bottom of the page that indicates the time required to retrieve

the product catalog. Note that the first item in the list indicates that the application retrieved

the product catalog from the data source.

Note: You may need to refresh the page several times to obtain a stable reading. The value

shown for the first request may be greater because ASP.NET needs to compile the page.

Page 26: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 26

Figure 16

Running the application without the cache

7. Observe the Object ID indicator shown above the product catalog and notice how it changes

every time you refresh the page indicating that the repository returns a different object for each

call.

8. Now, click Yes in Use cache for product data and wait for the page to refresh. Notice that the

first item in the list indicates that it was still necessary for the application to retrieve the

product catalog from the data source because the information has yet to be cached.

Page 27: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 27

9. Click Products, or refresh the page in the browser. This time, the application retrieves the

product data from the Windows Azure AppFabric Caching and the elapsed time should be

lower. Confirm that the first item in the list indicates that the source of the information is the

cache.

Figure 17

Running the application with the cache enabled

Task 3 – Enabling the Local Cache

Page 28: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 28

When using the Caching service, you have the option of using a local cache that allows objects to be

cached in-memory at the client, as well as being stored in the cache cluster. In this task, you enable the

local cache and compare the access time with the remote case.

1. Open the ProductsRepository.cs file in the Services folder of the MVCAzureStore project.

2. In the ProductsRepository class, replace the current fields and constructor with the following

code, to add the logic of managing the localCache configuration.

(Code Snippet – BuildingAppsWithCachingService-Ex2- ProductsRepository with local cache-CS)

C#

...

private static DataCacheFactory CacheFactory;

private static DataCacheFactoryConfiguration FactoryConfig;

private bool enableCache = false;

private bool enableLocalCache = false;

public ProductsRepository(bool enableCache, bool enableLocalCache)

{

this.enableCache = enableCache;

this.enableLocalCache = enableLocalCache;

if (enableCache)

{

if (enableLocalCache && (FactoryConfig == null ||

!FactoryConfig.LocalCacheProperties.IsEnabled))

{

TimeSpan localTimeout = new TimeSpan(0, 0, 30);

DataCacheLocalCacheProperties localCacheConfig = new

DataCacheLocalCacheProperties(10000, localTimeout,

DataCacheLocalCacheInvalidationPolicy.TimeoutBased);

FactoryConfig = new DataCacheFactoryConfiguration();

FactoryConfig.LocalCacheProperties = localCacheConfig;

CacheFactory = new DataCacheFactory(FactoryConfig);

}

else if (!enableLocalCache && (FactoryConfig == null ||

FactoryConfig.LocalCacheProperties.IsEnabled))

{

CacheFactory = null;

}

}

if (CacheFactory == null)

{

FactoryConfig = new DataCacheFactoryConfiguration();

CacheFactory = new DataCacheFactory(FactoryConfig);

Page 29: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 29

}

}

...

3. Open the HomeController.cs file in the Controllers folder and find the Index action. Locate the

line that instantiates a new ProductsRepository and Replace those lines with the following

(Code Snippet – BuildingAppsWithCachingService-Ex2- GetProducts LocalCache-CS)

C#

public class HomeController : Controller

{

...

public ActionResult Index()

{

bool enableCache = (bool)this.Session["EnableCache"];

bool enableLocalCache = (bool)this.Session["EnableLocalCache"];

// retrieve product catalog from repository and measure the elapsed time

Services.IProductRepository productRepository = new

Services.ProductsRepository(enableCache, enableLocalCache);

Services.IProductRepository productRepository =

new Services.ProductsRepository(enableCache);

Stopwatch stopwatch = new Stopwatch();

stopWatch.Start();

var products = productRepository.GetProducts();

...

}

4. In the same method, locate the code that creates a new IndexViewModel add the following

property

C#

public class HomeController : Controller

{

...

public ActionResult Index()

{

bool enableCache = (bool)this.Session["EnableCache"];

bool enableLocalCache = (bool)this.Session["EnableLocalCache"];

// retrieve product catalog from repository and measure the elapsed time

Services.IProductRepository productRepository =

new Services.ProductsRepository(enableCache, enableLocalCache);

Page 30: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 30

Stopwatch stopwatch = new Stopwatch();

stopWatch.Start();

var products = productRepository.GetProducts();

stopWatch.Stop();

// add all products currently not in session

var itemsInSession = this.Session["Cart"] as List<string> ?? new

List<string>();

var filteredProducts = products.Where(item =>

!itemsInSession.Contains(item));

IndexViewModel model = new IndexViewModel()

{

Products = filteredProducts,

ElapsedTime = stopWatch.ElapsedMilliseconds,

IsCacheEnabled = enableCache,

IsLocalCacheEnabled = enableLocalCache,

ObjectId = products.GetHashCode().ToString()

};

return View(model);

}

...

}

5. Add a new action method to the HomeController to enable or disable the local cache from the

UI of the application.

(Code Snippet – BuildingAppsWithCachingService-Ex2-EnableLocalCache method-CS)

C#

public class HomeController : Controller

{

...

public ActionResult EnableLocalCache(bool enabled)

{

this.Session["EnableLocalCache"] =

!((bool)this.Session["EnableLocalCache"]);

return RedirectToAction("Index");

}

}

6. Open Index.aspx file in the Views\Home folder and add the following code above the

elapsedTime div.

Page 31: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 31

(Code Snippet – BuildingAppsWithCachingService-Ex2-EnableLocalCache Option-HTML)

HTML

<fieldset>

<legend>Cache settings for product data</legend>Enable Cache:

<%if (Model.IsCacheEnabled)

{ %>

Yes | <%=Html.ActionLink("No", "EnableCache", new { enabled = false

}).ToString()%>

<%}

else

{ %>

<%=Html.ActionLink("Yes", "EnableCache", new { enabled = true

}).ToString()%> | No

<%} %>

<br />

<%if (Model.IsCacheEnabled)

{ %>

Use Local Cache:

<%if (Model.IsLocalCacheEnabled)

{ %>

Yes |

<%=Html.ActionLink("No", "EnableLocalCache", new { enabled = false

}).ToString()%>

<%}

else

{ %>

<%=Html.ActionLink("Yes", "EnableLocalCache", new { enabled = true

}).ToString()%>

| No

<%} %>

<%} %>

<div id="elapsedTime">Elapsed time: <%:Model.ElapsedTime.ToString()%>

milliseconds.</div>

</fieldset>

7. Press F5 to build and launch the application in the development fabric.

8. When you start the application, the cache and the local cache are initially disabled. Enable

cache and then the local cache.

9. Refresh the page several times until the elapsed time stabilizes. Notice that the reading is now

significantly lower, possibly under a millisecond, showing that the application now retrieves the

data from the local in-memory cache.

Page 32: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 32

Figure 18

Using the local cache

10. Observe that, each time you refresh the page, the Object ID shown above the product catalog

remains constant indicating that the repository now returns the same object each time.

Note: This is an important aspect to consider. Previously, with the local cache disabled,

changing an object retrieved from the cache had no effect on the cached data and subsequent

fetches always returned a fresh copy. Once you enable the local cache, it stores references to

in-memory objects and any changes to the object directly affect the cached data.

Page 33: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 33

You should be aware of this when using the cache in your own applications and consider that,

after changing a cached object and later retrieving the same object from the cache, it may or

may not include these changes depending on whether it is returned by the local or remote

cache.

11. Wait for at least 30 seconds and then refresh the page one more time. Notice that the elapsed

time is back to its original value and that the object ID has changed, showing that the cached

item has expired and been purged from the cache due to the expiration policy set on the object

when it was stored.

Exercise 3: Creating a Reusable and

Extensible Caching Layer

In the previous exercise, you explored the fundamental aspects of using the Windows Azure AppFabric

Caching by directly updating the methods in the data access class to cache data retrieved from the

repository. While this was approach yields significant benefits, it requires you to change each one of

your data access methods to enable caching. An alternative approach that does not require changes to

your existing data access classes would be advantageous.

In this exercise, you explore building a caching layer on top of your existing data access classes that will

allow you to plug in different caching providers, or even remove them altogether, through simple

configuration changes.

To build this layer, you implement an abstract caching class named CachedDataSource that provides

support for storing and removing data in the cache. You then derive from this class to create a caching

equivalent for any data source in your application. The only requirement is that your data source

implements a contract to define its data access operations. The caching class encapsulates a caching

provider, which you need to provide in its constructor, and provides methods to retrieve and remove

data from the cache.

The data retrieval method in the caching class receives a cache key that uniquely identifies a cached

item, a delegate that retrieves data from the data source, and a cache expiration policy that determines

when to purge the item from the cache. This method implements the classic caching pattern where it

first attempts to retrieve an item from the cache and, if it does not find a copy, uses the supplied

delegate to retrieve the data from the source and then stores it in the cache.

The implementation of the CachedDataSource class is completely reusable, allowing you to use any

caching provider that fits your requirements. To specify a caching provider, you supply an ObjectCache

Page 34: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 34

instance to its constructor. The ObjectCache class, part of the System.Runtime.Caching namespace, was

introduced in the .NET Framework 4 to make caching available for all applications. This abstract class

represents an object cache and provides base methods and properties for accessing an underlying cache

provider. The .NET Framework already offers a concrete implementation of this class that provides an

in-memory cache, the MemoryCache.

To use a given cache service with the CachedDataSource derived class, you need to supply an

ObjectCache implementation specific to the caching provider. A good approach is to create a data

source factory that allows you to choose a suitable caching implementation based on your needs.

Replacing the caching provider is then simply a matter of changing a setting in the configuration file.

Currently, the Windows Azure AppFabric Caching does not supply its own ObjectCache implementation.

Nevertheless, you can create one that provides a wrapper around its services. You will find an example

of such an implementation, the AppFabricCacheProvider, in the Assets folder of this lab. This class

derives from ObjectCache to expose the services in the Windows Azure AppFabric Caching.

To take advantage of this caching implementation in the Azure Store application, you will create a

caching counterpart of the ProductsRepository class. The application uses this class, which implements

an IProductsRepository contract with a single GetProducts operation, to retrieve catalog information

from SQL Azure. To create a caching products catalog source, you need to perform the following steps:

Create a new CachingProductsReposity class that inherits from CachedDataSource.

Add a constructor to the new class that receives an IProductRepository parameter with an

instance of the non-caching data source class as well as an ObjectCache parameter with an

instance of the caching provider to use.

Implement each method in the IProductRepository interface by calling the

RetrievedCachedData method in the base class and supplying a delegate that calls the original

data source class.

Task 1 – Implementing a Caching Data Source Base Class

In this task, you create the abstract class that you will use as the base class for your caching data source

classes. You can take advantage of this general-purpose class in any project that requires a caching layer.

1. Start Microsoft Visual Studio 2010 as an administrator.

2. Open the Begin solution located at Ex3-ReusableCachingImplementation inside the Source

folder of the lab.

Important: Before you execute the solution, make sure that the start-up project is set. For

MVC projects, the start page must be left blank.

To set the start up project, in Solution Explorer, right-click the AzureStoreService project and

then select Set as StartUp Project.

Page 35: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 35

To set the start page, in Solution Explorer, right-click the MVCAzureStore project and select

Properties. In the Properties window, select the Web tab and in the Start Action, select

Specific Page. Leave the value of this field blank.

3. In the Web.config file, update the NorthwindEntities connection string to point to your

database. Replace [YOUR-SQL-AZURE-SERVER-ADDRESS], [SQL-AZURE-USERNAME], and [SQL-

AZURE-PASSWORD] with the SQL Azure database server name, Administrator Username and

Administrator password that you registered at the portal and used for creating the database

during setup.

Note: Make sure that you follow the instructions of the setup section to create a copy of the

Northwind2 database in your own SQL Azure account and configure your SQL Azure firewall

settings.

4. Add a reference to the System.Runtime.Caching assembly in the MVCAzureStore project.

5. In the Services folder of the MVCAzureStore project, add a new folder named Caching.

6. Inside the Caching folder created in the previous step, add a new class file named

CachedDataSource.cs.

7. In the new class file, add a namespace directive for System.Runtime.Caching.

C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Runtime.Caching;

...

8. Specify an abstract modifier for the CachedDataSource class.

C#

public abstract class CachedDataSource

{

}

9. Add the following (highlighted) member fields to the class.

(Code Snippet – BuildingAppsWithCachingService-Ex3-CachedDataSource member fields-CS)

C#

public abstract class CachedDataSource

{

Page 36: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 36

private readonly ObjectCache cacheProvider;

private readonly string regionName;

}

10. Now, define a constructor that receives an object cache and a region name as parameters, as

shown (highlighted) below.

(Code Snippet – BuildingAppsWithCachingService-Ex3-CachedDataSource constructor-CS)

C#

public abstract class CachedDataSource

{

...

public CachedDataSource(ObjectCache cacheProvider, string regionName)

{

if (cacheProvider == null)

{

throw new ArgumentNullException("cacheProvider");

}

if (cacheProvider is MemoryCache)

{

regionName = null;

}

this.cacheProvider = cacheProvider;

this.regionName = regionName;

}

}

Note: The CachedDataSource constructor receives an ObjectCache instance as a parameter,

which provides methods and properties for accessing an object cache, as well as a region

name. A cache region is a partition in the cache used to organize cache objects.

11. Next, add the following (highlighted) method to retrieve data from the cache.

(Code Snippet – BuildingAppsWithCachingService-Ex3-RetrieveCachedData method-CS)

C#

public abstract class CachedDataSource

{

...

protected T RetrieveCachedData<T>(string cacheKey, Func<T> fallbackFunction,

CacheItemPolicy cachePolicy) where T : class

{

Page 37: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 37

var data = this.cacheProvider.Get(cacheKey, this.regionName) as T;

if (data != null)

{

return data;

}

data = fallbackFunction();

if (data != null)

{

this.cacheProvider.Add(new CacheItem(cacheKey, data, this.regionName),

cachePolicy);

}

return data;

}

}

Note: The RetrieveCachedData method uses the provided key to retrieve a copy of the

requested item from the cache. If the data is available, it returns it; otherwise, it uses the

provided fallback delegate to obtain the information from the data source and then caches the

result using the supplied cache expiration policy.

12. Finally, add a method to delete items from the cache.

(Code Snippet – BuildingAppsWithCachingService-Ex3-RemoveCachedData method-CS)

C#

public abstract class CachedDataSource

{

...

protected void RemoveCachedData(string cacheKey)

{

this.cacheProvider.Remove(cacheKey, this.regionName);

}

}

13. Save the CachedDataSource.cs file.

-

Task 2 – Building a Caching Product Catalog Repository

Once you have created an abstract base class for caching data sources, you now create a concrete

implementation that will provide a caching alternative for the ProductsRepository class. This task

Page 38: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 38

represents the steps you would typically follow when creating a caching layer for your data access code

using the CachedDataSource class.

1. Inside the Services\Caching folder of the MVCAzureStore project, add a new class file named

CachedProductsRepository.cs.

2. In the new class file, append a namespace directive for System.Runtime.Caching.

C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Runtime.Caching;

...

3. Change the declaration for the CachedProductsRepository class to derive from both

CachedDataSource and IProductRepository, as shown (highlighted) below.

C#

public class CachedProductsRepository

: CachedDataSource, IProductRepository

{

}

Note: The caching data source class derives from CachedDataSource to provide the necessary

caching behavior, as well as implementing the same contract used by the original data source

class.

4. Add the following code to define a constructor and declare a member field that holds a

reference to the underlying data source, as shown (highlighted) below.

(Code Snippet – BuildingAppsWithCachingService-Ex3-CachedProductsRepository constructor-

CS)

C#

public class CachedProductsRepository : CachedDataSource, IProductRepository

{

private readonly IProductRepository repository;

public CachedProductsRepository(IProductRepository repository, ObjectCache

cacheProvider) :

base(cacheProvider, "Products")

{

Page 39: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 39

this.repository = repository;

}

}

Note: The CachedProductsRepository constructor initializes its base class using the supplied

cache provider and saves a reference to the underlying data source in a member field. The

class defines a “Products” cache region.

5. Finally, fulfill the IProductRepository contract by implementing the GetProducts method, as

shown (highlighted) below.

(Code Snippet – BuildingAppsWithCachingService-Ex3-GetProducts method -CS)

C#

public class CachedProductsRepository : CachedDataSource, IProductRepository

{

...

public List<string> GetProducts()

{

return RetrieveCachedData(

"allproducts",

() => this.repository.GetProducts(),

new CacheItemPolicy { AbsoluteExpiration = DateTime.UtcNow.AddMinutes(1)

});

}

}

Note: The GetProducts method calls RetrieveCachedData in the base class, passing in a key

that identifies the cached item, in this case “allproducts”, a fallback delegate in the form of a

lambda expression that simply calls the GetProducts method in the original data source, and a

CacheItemPolicy to set the expiration of the item to 1 minute.

Because the IProductRepository contract is so simple, this is all that is required to provide a

caching implementation. Typically, your data sources will have more than one method, but the

basic approach should not change, allowing you to implement every method by copying this

same pattern.

Task 3 – Creating a Data Source Factory Class

Page 40: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 40

In this task, you create a factory class that can return data source instances. The factory determines the

cache provider to use from the application configuration settings and returns a data source suitably

configured to use the chosen cache provider.

1. Add a copy of the AppFabricCacheProvider.cs file located in the Assets folder of the lab to the

MVCAzureStore project and place it in its Services\Caching folder.

Note: The AppFabricCacheProvider class implements an ObjectCache that wraps the services

provided by the Windows Azure AppFabric Cache Service.

2. Inside the Services folder of the MVCAzureStore project, add a new class file named

DataSourceFactory.cs.

3. In the new class file, insert namespace directives for System.Configuration,

System.Runtime.Caching, and MVCAzureStore.Services.Caching.

(Code Snippet – BuildingAppsWithCachingService-Ex3-DataSourceFactory namespaces-CS)

C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Configuration;

using System.Runtime.Caching;

using MVCAzureStore.Services.Caching;

4. Now, add the following code to define a type constructor for the DataSourceFactory class and

declare a static field that holds a reference to the configured cache service provider, as shown

(highlighted) below.

(Code Snippet – BuildingAppsWithCachingService-Ex3-DataSourceFactory class constructor-CS)

C#

public class DataSourceFactory

{

private static readonly ObjectCache cacheProvider;

static DataSourceFactory()

{

string provider =

ConfigurationManager.AppSettings["CacheService.Provider"];

if (provider != null)

{

switch

(ConfigurationManager.AppSettings["CacheService.Provider"].ToUpperInvariant())

Page 41: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 41

{

case "APPFABRIC":

cacheProvider = new AppFabricCacheProvider();

break;

case "INMEMORY":

cacheProvider = MemoryCache.Default;

break;

}

}

}

}

Note: The class constructor reads the CacheService.Provider setting from the configuration and

initializes the cache provider for the application based on its value. In this example, two

different values for the setting are recognized, one for the Windows Azure AppFabric Caching

and another one for the default in-memory cache provider offered by the .NET Framework 4.

5. Next, add the following property to return the configured cache service provider.

(Code Snippet – BuildingAppsWithCachingService-Ex3- CacheProvider property-CS)

C#

public class DataSourceFactory

{

...

public static ObjectCache CacheProvider

{

get { return cacheProvider; }

}

}

6. Finally, add a method to return an instance of the IProductRepository data source initialized

with the configured cache service provider.

(Code Snippet – BuildingAppsWithCachingService-Ex3-GetProductsRepository method-CS)

C#

public class DataSourceFactory

{

...

public static IProductRepository GetProductsRepository(bool enableCache)

{

var dataSource = new ProductsRepository();

if (enableCache && CacheProvider != null)

{

Page 42: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 42

return new CachedProductsRepository(dataSource, cacheProvider);

}

return dataSource;

}

}

Task 4 – Configuring the Application for Caching

In this task, you update the application to take advantage of the data source factory to instantiate the

product catalog data source. To complete the setup of the caching layer, you define the necessary

configuration settings to select a caching provider.

1. Open the HomeController.cs file in the Controllers folder and find the Index method. Inside this

method, replace the line that initializes the productRepository local variable with the code

shown (highlighted) below that uses the DataSourceFactory to retrieve an IProductRepository

instance.

C#

public class HomeController : Controller

{

...

public ActionResult Index()

{

bool enableCache = (bool)this.Session["EnableCache"];

// retrieve product catalog from repository and measure the elapsed time

Services.IProductRepository productRepository =

MVCAzureStore.Services.DataSourceFactory.GetProductsRepository(enableCache);

Stopwatch stopWatch = new Stopwatch();

stopWatch.Start();

...

}

...

}

2. To configure the DataSourceFactory, open the Web.config file and insert the following

(highlighted) appSettings section, ensuring that you add the content after the configSections

element and as a direct child of the configuration element.

(Code Snippet – BuildingAppsWithCachingService-Ex3-Web.config appSettings section-CS)

XML

<configuration>

Page 43: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 43

<configSections>

...

</configSections>

...

<appSettings>

<add key="CacheService.Provider" value="InMemory" />

</appSettings>

...

</configuration>

Note: If you host the application in a single node, the in-memory cache provider would be a

good choice.

3. Locate the dataCacheClient section and replace the [SERVICE-HOST-NAME] placeholder with

the name of the host for the Caching service endpoint that you provisioned earlier. For

example, for a Service URL http://your-namespace.cache.appfabriclabs.com /, set the name

attribute to your-namespace.cache.appfabriclabs.com. Replace the [AUTHORIZATION_INFO]

placeholder with the authorization token that you copied from the Cache Settings page.

4. Press F5 to build and test the enhanced caching implementation in the development fabric.

5. When you start the application, the cache is initially disabled. Click Yes in Use cache for product

data and wait for the page to refresh. Remember that the initial request after you enable the

cache includes the overhead required to retrieve the data and insert it into the cache.

6. Click Products, or refresh the page in the browser once again. This time, the application

retrieves the product data from the cache and the elapsed time should be lower, most likely

under a millisecond given that you have currently configured it to use the in-memory cache

provided by the .NET Framework.

7. Now, in the Web.config file, locate the appSettings section and set the value of the

CacheService.Provider setting to AppFabric.

XML

<configuration>

...

<appSettings>

<add key="CacheService.Provider" value="AppFabric" />

</appSettings>

...

</configuration>

Page 44: Hands-On Labaz12722.vo.msecnd.net/wazplatformtrainingcourse2-02/Labs/... · 2010-11-17 · training kit. Note: This lab requires a SQL Azure database to start. To build the Northwind2

Page | 44

Note: If you host the application in multiple nodes, the in-memory cache provider is no longer

a good choice. Instead, you can take advantage of the distributed cache offered by the

Windows Azure AppFabric Caching.

8. Save the Web.config file.

9. Suspend and Run the development fabric to restart and reload the configuration.

10. Make sure that the cache is still enabled and then refresh the page in the browser twice to

prime the cache with data. Notice that the elapsed times for the cached scenario have

increased indicating that the application is now using the Windows Azure AppFabric Caching

provider instead of the in-memory provider.

Summary

In this hands-on lab, you explored the use of the Windows Azure AppFabric Caching. You saw how to

configure session state to be cached across a cache cluster, allowing sessions to be preserved in the

presence of restarts and across multiple role instances hosting the application. In addition, you learnt

the basics of data caching with Windows Azure AppFabric and in particular, how to cache the results of

queries to a SQL Azure database. Finally, you looked at a reusable caching layer implementation that will

allow you to add a caching layer to your applications in a very simple manner.