Per-Request Caching


It is sometimes desirable to cache data or information only while the request is being processed independent of the component, server control, or page.

The ASP.NET Forums makes heavy use of personalization. In fact, each server control is responsible for checking the identity of the user and personalizing its display based on data relevant to the user. For example, users can define their own date and time display formats.

All user data is stored in a database. To guarantee consistency, user data is fetched on each request. All personalization data is accessible through a User class, which is retrieved from Users.GetLoggedOnUser. Any functionality within the application needing personalization can call this API. Internally, it will either return a per-request cached instance of the User class or connect through the data provider and populate a User instance.

The beauty is that all calls to GetLoggedOnUser are guaranteed to work, but the caller is completely unaware of whether it is receiving the User from the per-request cache or the data provider is creating a new User. Not creating a new User for each call saves on round trips to the database. For example, a page might have eight controls that need to access the User. Seven of those calls will be satisfied from the per-request cache; only the first will connect to the data store directly.

Implementing Per-Request Caching

Per-request caching is very easy to implement. Code Listing 6-5, from the ASP.NET Forums, shows how it is done.

Code Listing 6-5: Per-Request Caching

start example
 public static User GetLoggedOnUser() {
if (!HttpContext.Current.Request.IsAuthenticated)
return null;

return Users.GetUserInfo(HttpContext.Current.User.Identity.Name, true);
}

public static User GetUserInfo(String username, bool updateIsOnline) {
string userKey = "UserInfo-" + username;

// Attempt to return the user from Cache for users not online to save
// us a trip to the database.
if (updateIsOnline == false) {
if (HttpContext.Current.Cache[userKey] != null)
return (User) HttpContext.Current.Cache[userKey];
}

// Let's not go to the database each time we need the user's info
if (HttpContext.Current.Items[userKey] == null) {
// Hang on to the data for this request only
HttpContext.Current.Items[userKey] =
DataProvider.Instance().GetUserInfo(username,
updateIsOnline);
}

// Do we need to add the user into the Cache
if (updateIsOnline == false) {
if (HttpContext.Current.Cache[userKey] == null)
HttpContext.Current.Cache.Insert(userKey,
HttpContext.Current.Items[userKey],
null,
DateTime.Now.AddMinutes(1),
TimeSpan.Zero);
}

return (User) HttpContext.Current.Items[userKey];
}
end example

Per-request caching simply makes use of HttpContext.Items for data storage. HttpContext is a class that ASP.NET uses for the life cycle of a request/ response, and internally it is the class that many APIs forward to. For example, when you call Response.Write, you’re actually calling HttpContext.Response.Write.

The Items property is simply a name/value collection within which we can store arbitrary data. The data is available only for the life type of the HttpContext instance. The instance of HttpContext is created at the beginning of the request and destroyed at the end of the request. Once HttpContext goes out of scope (that is, it’s no longer needed because ASP.NET sent the response), all associated memory is released—including data stored in Items. Thus, HttpContext.Items is a perfect data store for per-request caching.




Microsoft ASP. NET Coding Strategies with the Microsoft ASP. NET Team
Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team (Pro-Developer)
ISBN: 073561900X
EAN: 2147483647
Year: 2005
Pages: 144

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net