Browse DevX
Sign up for e-mail newsletters from DevX


Caching Data with a Web Service in Enterprise Library : Page 4

If you've ever wondered whether you might be able to use a web service to cache data—or whether it would be fast enough to be useful—wonder no more.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Implementing the Caching Provider
With the proxy class in place, you can now create the provider for the Caching Application Block. The principles are the same as in the previously referenced article. The techniques for implementing design support for the Enterprise Library configuration tools are also the same.

The only real differences are that the Web Service Caching provider has three custom properties that you can set in the application configuration:

  • The default cache duration (sliding expiration time) that the provider will use if you do not specify the duration when caching an item
  • The name of the partition or filter value to pass to the web service with each cache method call
  • The URL of the target web service
Figure 3 shows how the design classes for the custom provider enable configuration through the Enterprise Library Configuration Console. The DefaultCacheDuration and PartitionName are set automatically to the default values shown in Figure 3, but users can edit them as required.

Figure 3. Configuring the Custom Web Service Caching Provider: You can see the three custom properties (in addition to the Name property) that it exposes.
In reality, the backing store provider (CustomWebServiceBackingStore.cs in the Caching\BackingStoreImplementations subfolder) has to pass calls only from the Caching Application Block to the proxy class methods. Therefore, the bulk of the work within the methods lies in converting values passed to the provider into the correct types for the proxy class.

The class declaration specifies the configuration element type for the class as an instance of the CustomWebServiceCacheStorageData class (discussed later). Notice that the provider class inherits from BaseBackingStore. Both these features are requirements for a simple custom cache backing store provider:

[ConfigurationElementType(typeof( CustomWebServiceCacheStorageData))] public class CustomWebServiceBackingStore : BaseBackingStore { ...

The Provider Class Constructor
The provider constructor takes the values passed from its configuration data storage class and stores them in local variables so it can pass them to the appropriate proxy methods. Here's the class constructor and the local variable declarations:

// name of the name/value pairs declared in the application // configuration file <backingStores> section private const String serviceUrlAttribute = "webServiceUrl"; private const String servicePartitionNameAttribute = "partitionName"; private const String serviceDefaultDurationAttribute = "defaultCacheDuration"; // local variables private ICustomCacheWebService serviceProxy = null; private String wsUrl = String.Empty; private String wsPartition = String.Empty; private int wsDefaultDuration = 0; public CustomWebServiceBackingStore(String serviceUrl, String partitionName, int defaultCacheDuration) { if (serviceUrl != String.Empty && partitionName != String.Empty && defaultCacheDuration != 0) { wsUrl = serviceUrl; wsPartition = partitionName; wsDefaultDuration = defaultCacheDuration; } else { throw new Exception( "Error in application configuration"); } }

Obtaining a Reference to the Proxy Class
Every property and method in the provider must obtain a reference to the proxy to call its methods; therefore, it makes sense to hang on to the reference where possible. This is true even in ASP.NET applications, where each page load instantiates the block and the provider, because the block often calls more than one method as part of a caching operation (for example, it calls the RemoveOldItem method before calling the AddNewItem method).

Therefore, the provider includes a private method that returns a new or existing instance of the proxy class. This instance (as an ICustomCacheWebService type) is stored locally in the variable named serviceProxy:

// get a new or existing instance of the // Web Service Proxy object private ICustomCacheWebService GetWebServiceProxy() { if (serviceProxy == null) { try { serviceProxy = new CustomCacheWebServiceProxy(wsUrl); } catch (Exception ex) { throw new Exception( "Cannot create Web Service Proxy", ex); } } return serviceProxy; }

Calling the Proxy Class Methods
Every method and property must pass the partition name to the proxy so that the target web service can access each item from the correct location. For example, the Flush method obtains a reference to the proxy and then passes the partition name to the Flush method of the proxy:

public override void Flush() { ICustomCacheWebService proxy = GetWebServiceProxy(); String errMessage = String.Empty; try { errMessage = proxy.Flush(wsPartition); } catch (Exception ex) { throw new Exception( "Failed to execute Flush method", ex); } if (errMessage != String.Empty) { throw new Exception( "Cannot flush Web Service cache partition '" + wsPartition + "'. Web Service error: " + errMessage); } }

To provide enhanced debugging and error handling capabilities (always a good idea when working with web services), the method catches any exceptions and provides details of what went wrong. If an error occurs, the service passes the error message back to the proxy, and on to the provider, as a String value that the provider can return to the user. If no error occurs, the web service returns an empty string.

Author's Note: This article shows the C# code for the sample web service methods and the test application, but you can get the VB.NET code by downloading and opening the sample projects.

Thanks for your registration, follow us on our social networks to keep up-to-date