Update:25th-Sep-2012 Update:24th-Sep-2012
Dependency Management support for Oracle coming soon.....stay tuned!
Introduction:

Cache Provider for .NET helps enterprise applications leverage the benefits of the established Provider Model in .NET while enabling Cache for the applications. Driven by configuration, it abstracts application code from the Cache Store and provides an API which is easy to use. It ships with AppFabric Cache Provider (code named Velocity) and Classic Cache Provider and can be used with the following Application Models: ASP.NET, Windows Forms, Windows Services, WCF and WPF.

Usage Scenarios:
  • As a cache layer in .NET applications to improve performance by encaching reference data with the benefit of replaceable caching store through configuration.
  • Caching Service Responses (WCF,ASMX) wherever suitable. See utilities in the source code for How-to
  • Caching ASP.NET Page responses wherever suitable. See utilities in the source code for How-to
  • Automatic Cache Sync as dependencies change. Facilitates zero cache-miss when a client accesses the same data next time.


Benefits:
  • Cache Store can be changed using configuration settings.
  • One provider for In-Proc and one for out-of-proc Cache shipped.
  • Dependency management support for both In-Proc and out-of-proc Cache. Currently, provides support for SQL Server.
  • Support to automatically update cache with new data incase dependencies change. Callbacks can be invoked on the UI thread irrespective of Application model.
  • Support to manage dependencies for out-of-proc Cache even if all the cache client applications go out-of-scope through a separate windows service.
  • Sample usage scenarios for ASP.NET, WCF, WPF, Win Forms provided in the download.
  • Custom HttpModule based caching for ASP.NET response provided.
  • Custom OperationBehavior based WCF Operation response caching provided.

Steps to use CacheProvider in a .NET solution
1. Install and configure Windows Server AppFabric (if you want to use AppFabric Cache)
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=467e5aa5-c25b-4c80-a6d2-9f8fb0f337d2&displaylang=en

2. To enable SqlDependency notification, run the following statements in the DB in context:

                ALTER DATABASE <DB_NAME> SET ENABLE_BROKER;
                CREATE QUEUE ContactChangeMessages;
                CREATE SERVICE ContactChangeNotifications  ON QUEUE ContactChangeMessages   
                ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);


3. Make sure to enable Notifications support for the CacheName(s) required by following these steps:
. Start “Caching Administration Windows PowerShell” from AppFabric Menu.
  • Type the command: Get-CacheConfig <CacheName>
Where CacheName is the NamedCache value or “default”
  • Note that the property “NotificationsEnabled” is set to True. If not, run the following command to set it:
  • Set-CacheConfig -CacheName <CacheName> -NotificationsEnabled True

4. Add Reference to “CacheProvider.dll” or CacheProvider project (if using Source code).
5. Add reference to “CacheProvider.Classic.dll” and\or “CacheProvider.AppFabric.dll” depending on which provider you want to use.

6. Sample Configuration:

  <cacheProvider defaultProvider="ClassicCacheProvider">
    <providers>
      <add name="ClassicCacheProvider"
           type="CacheProvider.Classic.ClassicCacheProvider, CacheProvider.Classic"
           defaultExpirationTimeInMS="20000" />

      <add name="AppFabricCacheProvider"
           type="CacheProvider.AppFabric.AppFabricCacheProvider, CacheProvider.AppFabric"
           defaultExpirationTimeInMS="20000"
           dataCacheFactoryPoolSize="5"
           eagerPooling="true" />
    </providers>
  </cacheProvider>

 <!--AppFabric Configuration-->
  <dataCacheClient>
    <!--pollInterval is in seconds-->
    <clientNotification pollInterval="1" maxQueueLength="10000"/>
    <hosts>
      <host
         name="Rahul-PC"
         cachePort="22233"/>
    </hosts>
    <!--<securityProperties mode="Transport" protectionLevel="EncryptAndSign" />
    <transportProperties connectionBufferSize="131072" maxBufferPoolSize="268435456"
                         maxBufferSize="8388608" maxOutputDelay="2" channelInitializationTimeout="60000"
                         receiveTimeout="600000"/>-->
  </dataCacheClient>



7. Sample Usage:

        public List<Product> GetProductList()
        {

            const string key = "SqlDependencyCache";

            var products = CacheBroker.Get<List<Product>>(key);

            if (products == null)
            {
                products = GetProductsFromDB();

                CacheBroker.Put(key, products);                
            }

            return products;
        }

        private static List<Product> GetProductsFromDB()
        {
            var products = new List<Product>();
            using (var connection = new SqlConnection(GetConnectionString()))
            using (var sqlCommand = new SqlCommand(GetSQL(), connection))
            {
                connection.Open();
                IDataReader reader = sqlCommand.ExecuteReader();
                if (reader != null)
                {
                    int productIdIndex = reader.GetOrdinal("ProductId");
                    int productNameIndex = reader.GetOrdinal("ProductName");
                    int productLocationIndex = reader.GetOrdinal("Location");
                    int productQuantityIndex = reader.GetOrdinal("Quantity");
                    while (reader.Read())
                    {
                        var product = new Product()
                                          {
                                              ProductId = reader.GetInt32(productIdIndex),
                                              Name = reader.GetString(productNameIndex),
                                              Location = reader.GetString(productLocationIndex),
                                              Quantity = reader.GetInt16(productQuantityIndex)
                                          };
                        products.Add(product);
                    }
                }
            }

            return products;
        }



8. Sampe Usage with Dependency:

            const string cacheKey = "Products";
            var products = CacheBroker.Get<List<ProductInfo>>(cacheKey); //ProductInfo is an entity
            if (products == null)
            {
                using (var context = new AdventureworksDataContext(GetConnectionString())) //using LINQ2SQL
                {
                    products = GetProductDetails(context); //Retuns List<ProductInfo>

                    var dependencyCommand = from product in context.Products
                                            select product;

                    var dependencyInfo = new DependencyInfo(DependencyInfo.DependencyTypes.SQLDependency)
                                                           {
                                                               DBConnectionString = GetConnectionString(),
                                                               DBName = "AdventureWorks",
                                                               IsSQLSelectQuery = true,
                                                               SelectQuery = context.GetCommand(dependencyCommand).CommandText
                                                           };

                    CacheBroker.Put(cacheKey, products, dependencyInfo);
                }
            }


9. Logical Block Diagram:

CacheProviderBlockDiagram1.jpg


To download, please visit the Source Code tab.

Last edited Sep 25, 2012 at 2:21 PM by hariharanpalani, version 41