[ASP.NET]Implémentation d’un singleton partagé dans le cache d’une web application
Emilien Martinez | 3 novembre 2008 | 15:51Aujourd’hui je vous présente la dernière chose intéressante que j’ai développé, il s’agit d’un dictionnaire permettant le chargement de données à la demande. En effet ce système permet de monter des données en mémoire pour tous les utilisateurs. Je m’explique, lors du lancement de l’application, notre dictionnaire est vide. Un utilisateur demande l’accès à une certaine ressource, nous la montons donc en mémoire et cela pour tous les utilisateurs. Cela à pour but de minimiser les accès base tout en montant une fois pour toute des informations communes. Pour cela, deux design patterns ont été implémentés : l’un classique, le singleton et l’autre un peu plus exotique, le double check. Le pattern double check permet de vérifier que personne n’écrit dans notre dictionnaire lorsque nous souhaitons y écrire.
Singleton :
Â
namespace appli.transerse
{
   public class CacheDictionary
   {
       private Cache _cache;
       private static CacheDictionary INSTANCE = null;
       private System.Collections.Generic.Dictionary<string, string> _dictionnary;
       public Cache Cache
       {
           get { return _cache; }
           set { _cache = value; }
       }
       public static CacheDictionary getInstance()
       {
           if (INSTANCE == null)
           {
               INSTANCE = new CacheDictionary();
           }
           return INSTANCE;
       }
       public static CacheDictionary setInstance(CacheDictionary aht)
       {
           INSTANCE = aht;
           return INSTANCE;
       }
       private CacheDictionary()
       {
           _dictionnary = new System.Collections.Generic.Dictionary<string, string>();
       }
       public string GetContent(string title)
       {
           string myContent;
           bool IsExisting = INSTANCE._dictionnary.TryGetValue(title, out myContent);
           if (IsExisting)
           {
               return myContent;
           }
           else
           {
               lock (INSTANCE._dictionnary);
              Â
           }
           IsExisting = INSTANCE._dictionnary.TryGetValue(title, out myContent);
           if (!IsExisting)
           {
               myContent = HelpTextManager.GetText(title, null);
               INSTANCE._dictionnary.ContainsKey(title);
               INSTANCE._dictionnary.Add(title, myContent);
           }
          Â
           return myContent;
       }
      Â
       public static void Flush(String key, Object item, CacheItemRemovedReason reason)
       {
           Cache buffer = CacheDictionary.getInstance().Cache;
           CacheDictionary.setInstance(null);
           CacheDictionary.getInstance().Cache = buffer;
           InsertCache();
       }
       public static void InsertCache()
       {
           CacheDictionary.getInstance().Cache.Insert(“HelpText”, CacheDictionary.getInstance(), null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 0, 30), CacheItemPriority.Default, new CacheItemRemovedCallback(appli.transerse.CacheDictionary.Flush));
       }
   }
}
La méthode GetContent permet de récupérer les données de l’objet. Si les données ne sont pas présentes, on va les chercher dans la base de données et on les insère dans le dictionnaire de l’objet.
La méthode Flush est appelée lors du renouvellement du cache de l’application, elle récupère le Context.Cache et détruit l’instance de l’objet existante puis appèle la methode InsertCache pour pousser le nouvel objet dans le cache.
Création de l’instance est mise en cache au lancement de l’application dans le fichier Global.asax :
Â
void Application_Start(object sender, EventArgs e)
   {
       appli.transerse.CacheDictionary.getInstance().Cache = Context.Cache;
       Context.Cache.Insert(“cachetitle”, appli.transerse.CacheDictionary.getInstance(),null,Cache.NoAbsoluteExpiration,new TimeSpan(0,0,30),CacheItemPriority.Default,new CacheItemRemovedCallback(appli.transerse.CacheDictionary.Flush));
      Â
   }
Implémentation pour la récupération des donnés :
Â
CacheDictionary aht = CacheDictionary.setInstance((CacheDictionary)Cache[“cachetitle “]);
aht.GetContent(“my_key”)Â ;








