Click here to Skip to main content
15,888,527 members
Articles / Web Development / ASP.NET

Generic Cache Manager

Rate me:
Please Sign up or sign in to vote.
2.25/5 (5 votes)
2 Feb 2007CPOL2 min read 38.4K   204   11  
A Cache Manager built using Generics and the Microsoft Enterprise Library Cache Application Block.
using System;
using System.Security.Principal;
using System.Runtime.InteropServices;

using Microsoft.Practices.EnterpriseLibrary.Caching;

namespace DandTSoftware.GenericCacheManager
{
    /// <summary>
    /// Creates an Instance of the Cache Manager Class which is used for caching of objects of the type supplied
    /// </summary>
    /// <typeparam name="T">The Generic Type which this Cache Manager can handle</typeparam>
    public class GenericCacheManager<T>
    {
        #region Externs
        /// <summary>
        /// The RevertToSelf function terminates the impersonation of a client application
        /// </summary>
        /// <returns>If Reversion back to the orginal identify is successful, True is returned. Otherwise false</returns>
        [DllImport("advapi32", SetLastError = true)]
        private extern static bool RevertToSelf();
        #endregion

        #region Private Members
        /// <summary>
        /// The Microsoft Enterprise Library Cache Manager
        /// </summary>
        private CacheManager m_Cache = null;

        /// <summary>
        /// Should the Cache Manager change the Identity to the Application Pool?
        /// </summary>
        private bool m_UseAppBoolIdentity = false;

        /// <summary>
        /// The Current Identify of the Cache
        /// </summary>
        private WindowsIdentity m_CurrentWindowsIdentity;
        #endregion

        #region Constructor(s)
        /// <summary>
        /// Private Constructor
        /// </summary>
        private GenericCacheManager()
        {
            RevertToAppPool();

            try
            {
                this.m_Cache = CacheFactory.GetCacheManager();
            }
            catch (Exception ex)
            {
                // Cache is not Available!
                throw new CacheException("Caching is currently not configured correctly or it is unavailable.", ex);
            }
            finally
            {
                this.RevertToCurrentIdentity();
            }
        }

        /// <summary>
        /// Creates an Instance of the Cache Manager Class which is used for caching of objects of the type supplied
        /// </summary>
        /// <param name="UseAppBoolIdentity">Should the Cache Manager assume the identify of the application pool this application is running in.</param>
        public GenericCacheManager(bool UseAppBoolIdentity) : this()
        {
            this.m_UseAppBoolIdentity = UseAppBoolIdentity;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Adds an item to the Cache
        /// </summary>
        /// <param name="ID">The ID of the Cache</param>
        /// <param name="Value">The object to add to the Cache</param>
        public void AddToCache(int ID, T Value)
        {          
            this.AddToCache(ID.ToString(), Value);
        }
        /// <summary>
        /// Adds an item to the Cache
        /// </summary>
        /// <param name="ID">The ID of the Cache</param>
        /// <param name="Value">The object to add to the Cache</param>
        public void AddToCache(string ID, T Value)
        {
            this.Add(ID, Value);
        }
        /// <summary>
        /// Gets a Item from the Cache based on the ID suppiled
        /// </summary>
        /// <param name="ID">The ID of the Cached object</param>
        /// <returns>The Object from the Cache</returns>
        public T GetFromCache(int ID)
        {
            return this.GetFromCache(ID.ToString());
        }
        /// <summary>
        /// Gets a Item from the Cache based on the ID suppiled
        /// </summary>
        /// <param name="ID">The ID of the Cached object</param>
        /// <returns>The Object from the Cache</returns>
        public T GetFromCache(string ID)
        {
            return this.GetData(ID);
        }
        /// <summary>
        /// Checks the Cache Store to see if the Cache already contains the supplied Cache Key
        /// </summary>
        /// <param name="ID">The Key to check for in the Cache Store</param>
        /// <returns>TRUE if the Key is found, otherwise FALSE</returns>
        public bool Contains(int ID)
        {
            return this.Contains(ID.ToString());
        }
        /// <summary>
        /// Checks the Cache Store to see if the Cache already contains the supplied Cache Key
        /// </summary>
        /// <param name="ID">The Key to check for in the Cache Store</param>
        /// <returns>TRUE if the Key is found, otherwise FALSE</returns>
        public bool Contains(string ID)
        {
            return this.m_Cache.Contains(this.MakeKey(ID));
        }
        /// <summary>
        /// Removes a cached item from the Cache Store based on the Supplied ID
        /// </summary>
        /// <param name="ID">The ID of the cached object to remove</param>
        public void RemoveFromCache(int ID)
        {
            this.RemoveFromCache(ID.ToString());
        }
        /// <summary>
        /// Removes a cached item from the Cache Store based on the Supplied ID
        /// </summary>
        /// <param name="ID">The ID of the cached object to remove</param>
        public void RemoveFromCache(string ID)
        {
            this.m_Cache.Remove(this.MakeKey(ID));
        }
        #endregion

        #region Protected Methods
        protected void Add(int ID, T value)
        {
            this.Add(ID.ToString(), value);
        }

        protected void Add(string ID, T value)
        {
            this.RevertToAppPool();
            try
            {
                if (value == null)
                {
                    throw new NullReferenceException("value");
                }

                string Key = this.MakeKey(ID);

                if (this.m_Cache.Contains(Key))
                {
                    this.m_Cache.Remove(Key);
                }
                this.m_Cache.Add(Key, value);
            }
            finally
            {
                this.RevertToCurrentIdentity();
            }
        }

        protected T GetData(int ID)
        {
            return this.GetData(ID.ToString());
        }

        protected T GetData(string ID)
        {
            this.RevertToAppPool();

            try
            {
                return (T)this.m_Cache.GetData(this.MakeKey(ID));
            }
            finally
            {
                this.RevertToCurrentIdentity();
            }
        }

        protected void Remove(int ID)
        {
            this.Remove(ID.ToString());
        }

        protected void Remove(string ID)
        {
            this.RevertToAppPool();
            try
            {
                this.m_Cache.Remove(this.MakeKey(ID));
            }
            finally
            {
                this.RevertToCurrentIdentity();
            }
        }
        #endregion

        #region Private Methods

        /// <summary>
        /// Creates a Cache Key using the Type of the supplied geneeric
        /// </summary>
        /// <param name="ID">The ID of the Key</param>
        /// <returns>A well formed Cache Key</returns>
        private string MakeKey(string ID)
        {
            return string.Format("CACHEKEY_{0}_{1}", typeof(T).ToString(), ID);
        }

        /// <summary>
        /// Creates a Cache Key using the Type of the supplied geneeric
        /// </summary>
        /// <param name="ID">The ID of the Key</param>
        /// <returns>A well formed Cache Key</returns>
        private string MakeKey(int ID)
        {
            // Abstracted to MakeKey(string)
            return this.MakeKey(ID.ToString());
        }

        private void RevertToAppPool()
        {
            // Only premitting chaning of the identity if the constructor paramater allows it
            if (this.m_UseAppBoolIdentity)
            {
                try
                {
                    // Store our Current Identity
                    this.m_CurrentWindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();

                    if (!RevertToSelf())
                    {
                        // Error.. so throw it up
                        int ErrorId = Marshal.GetLastWin32Error();
                        throw new System.ComponentModel.Win32Exception(ErrorId);
                    }
                }
                catch (Exception ex)
                {
                    throw new CacheException("An error occured when trying to revert to application pool identity.", ex);
                }
            }
        }

        private void RevertToCurrentIdentity()
        {
            // Only premitting chaning of the identity if the constructor paramater allows it
            if (this.m_UseAppBoolIdentity)
            {
                try
                {
                    // Impersonate the current identity
                    this.m_CurrentWindowsIdentity.Impersonate();
                }
                catch (Exception ex)
                {
                    throw new CacheException("An error occured when trying to revert back to current windows identity.", ex);
                }
            }
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Archon Gnosis
Australia Australia
Just a developer with a little bit of knowledge, constantly learning.

Comments and Discussions