⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appcache.cs

📁 基于C/S的医疗卫生管理系统
💻 CS
字号:
using System;
using System.Xml;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Runtime.CompilerServices;

using Qeb.Support.Common;

namespace Qeb.Support.Cache
{
    public class AppCache
    {
        private XmlElement m_ObjectXmlMap;
        private static ICacheStrategy m_cs;
        private static AppCache m_AppCache;
        private XmlDocument m_RootXml = new XmlDocument();


        /// <summary>
        /// Private construtor, required for singleton design pattern.
        /// </summary>
        private AppCache()
        {
            //load the cache strategy object
            string typeName = AppConfig.GetValue("CacheStrategy", "Qeb.Support.Cache.DefaultCacheStrategy");
            
            Type type = Type.GetType(typeName,false);
            m_cs = (ICacheStrategy)Activator.CreateInstance(type, null);
            if (m_cs == null)
            {
                AppLog.Add(new AppError("AppCache创建策略类型不成功:" + typeName,this.GetType()));
            }

            //create an Xml used as a map between  xml expression and object cached in the
            //physical storage.
            m_ObjectXmlMap = m_RootXml.CreateElement("Cache");
            //build the internal xml document.
            m_RootXml.AppendChild(m_ObjectXmlMap);

        }

        /// <summary>
        /// Singlton method used to return the instance of Cache class
        /// </summary>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static AppCache GetInstance()
        {
            if (m_AppCache == null)
            {
                m_AppCache = new AppCache();
            }
            return m_AppCache;
        }

        /// <summary>
        /// Add the object to the underlying storage and Xml mapping document
        /// </summary>
        /// <param name="xpath">the hierarchical location of the object in Xml document </param>
        /// <param name="o">the object to be cached</param>
        public virtual void AddObject(string xpath, object o)
        {
            AddObject(xpath, o, false);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="xpath"></param>
        /// <param name="o"></param>
        /// <param name="removeOldObj">removeOldObject</param>
        public virtual void AddObject(string xpath, object o,bool removeOldObj)
        {
            if (removeOldObj)
                RemoveObject(xpath);

            //clear up the xpath expression
            string newXpath = PrepareXpath(xpath);
            int separator = newXpath.LastIndexOf("/");
            //find the group name
            string group = newXpath.Substring(0, separator);
            //find the item name
            string element = newXpath.Substring(separator + 1);

            XmlNode groupNode = m_ObjectXmlMap.SelectSingleNode(group);
            //determin if group is already exist?, if not, create one.
            if (groupNode == null)
            {
                lock (this)
                {
                    //build the xml tree
                    groupNode = CreateNode(group);
                }
            }
            //get a unique key to identity of object, it is used to map
            //between xml and object key used in the cache strategy
            string objectId = System.Guid.NewGuid().ToString();
            //create an new element and new attribute for this perticular object
            XmlElement objectElement = m_ObjectXmlMap.OwnerDocument.CreateElement(element);
            XmlAttribute objectAttribute = m_ObjectXmlMap.OwnerDocument.CreateAttribute("objectId");
            objectAttribute.Value = objectId;
            objectElement.Attributes.Append(objectAttribute);
            //Add the object element to the Xml document
            groupNode.AppendChild(objectElement);

            //add the object to the underlying storage through cache strategy
            m_cs.AddObject(objectId, o);
        }

        /// <summary>
        /// Retrieve the cached object using its hierarchical location
        /// </summary>
        /// <param name="xpath">hierarchical location of the object in xml document</param>
        /// <returns>cached object </returns>
        public virtual object RetrieveObject(string xpath)
        {
            object o = null;
            XmlNode node = m_ObjectXmlMap.SelectSingleNode(PrepareXpath(xpath));
            //if the hierarchical location existed in the xml, retrieve the object
            //otherwise, return the object as null
            if (node != null)
            {
                string objectId = node.Attributes["objectId"].Value;
                //retrieve the object through cache strategy
                o = m_cs.RetrieveObject(objectId);
            }
            return o;

        }

        /// <summary>
        /// Remove the object from the storage and clear the Xml assocated with
        /// the object
        /// </summary>
        /// <param name="xpath">hierarchical locatioin of the object</param>
        public virtual void RemoveObject(string xpath)
        {
            XmlNode result = m_ObjectXmlMap.SelectSingleNode(PrepareXpath(xpath));
            if (result == null) return;

            //check if the xpath refers to a group(container) or
            //actual element for cached object
            if (result.HasChildNodes)
            {
                //remove all the cached object in the hastable
                //and remove all the child nodes 
                XmlNodeList objects = result.SelectNodes("*[@objectId]");
                string objectId = "";
                foreach (XmlNode node in objects)
                {
                    objectId = node.Attributes["objectId"].Value;
                    node.ParentNode.RemoveChild(node);
                    //use cache strategy to remove the objects from the 
                    //underlying storage
                    m_cs.RemoveObject(objectId);

                }

            }
            else
            {
                //just remove the element node and the object associate with it
                string objectId = result.Attributes["objectId"].Value;
                result.ParentNode.RemoveChild(result);
                m_cs.RemoveObject(objectId);
            }
        }

        /// <summary>
        /// Retrive a list of object under a hierarchical location
        /// </summary>
        /// <param name="xpath">hierarchical location</param>
        /// <returns>an array of objects</returns>
        public virtual object[] RetrieveObjectList(string xpath)
        {
            XmlNode group = m_ObjectXmlMap.SelectSingleNode(PrepareXpath(xpath));
            XmlNodeList results = group.SelectNodes(PrepareXpath(xpath) + "/*[@objectId]");
            ArrayList objects = new ArrayList();
            string objectId = null;
            //loop through each node and link the object in object[]
            //to objects stored via cache strategy
            foreach (XmlNode result in results)
            {
                objectId = result.Attributes["objectId"].Value;
                objects.Add(m_cs.RetrieveObject(objectId));
            }
            //convert the ArrayList to object[]
            return (object[])objects.ToArray(typeof(System.Object));
        }


        /// <summary>
        /// CreateNode is responsible for creating the xml tree that is
        /// specificed in the hierarchical location of the object.
        /// </summary>
        /// <param name="xpath">hierarchical location</param>
        /// <returns></returns>
        private XmlNode CreateNode(string xpath)
        {
            string[] xpathArray = xpath.Split('/');
            string root = "";
            XmlNode parentNode = (XmlNode)m_ObjectXmlMap;
            //loop through the array of levels and create the corresponding node for each level
            //skip the root node.
            for (int i = 1; i < xpathArray.Length; i++)
            {
                XmlNode node = m_ObjectXmlMap.SelectSingleNode(root + "/" + xpathArray[i]);
                // if the current location doesn't exist, build one
                //otherwise set the current locaiton to the it child location
                if (node == null)
                {
                    XmlElement newElement = m_ObjectXmlMap.OwnerDocument.CreateElement(xpathArray[i]);
                    parentNode.AppendChild(newElement);
                }
                //set the new location to one level lower
                root = root + "/" + xpathArray[i];
                parentNode = m_ObjectXmlMap.SelectSingleNode(root);
            }
            return parentNode;
        }

        /// <summary>
        /// clean up the xpath so that extra '/' is removed
        /// </summary>
        /// <param name="xpath">hierarchical location</param>
        /// <returns></returns>
        private string PrepareXpath(string xpath)
        {
            string[] xpathArray = xpath.Split('/');
            xpath = "/Cache";
            foreach (string s in xpathArray)
            {
                if (s != "")
                {
                    xpath = xpath + "/" + s;
                }
            }
            return xpath;
        }
    }



    /// <summary>
    /// the interface for cache strategy.
    /// each class that is pluggable to the SAF.Cache must 
    /// implement this interface.
    /// </summary>
    public interface ICacheStrategy
    {
        void AddObject(string objId, object o);
        void RemoveObject(string objId);
        object RetrieveObject(string objId);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -