/// <summary> /// Extrait du cache les éléments répondants au prédicat transmis. /// </summary> /// <typeparam name="T">Type d'élément</typeparam> /// <param name="selector">Prédicat de sélection</param> /// <param name="loadAllMethod">Méthode de chargement de tous les objets, qui sera appelée si le cache n'est pas déjà initialisé</param> /// <param name="forceReloadIfMissing">Force le rechargement si un élément n'est pas trouvé</param> /// <returns></returns> public static List <T> GetElements <T>(Predicate <T> selector, LoadAllMethod <T> loadAllMethod, bool forceReloadIfMissing = true) where T : class { List <T> listeCache = GetAll(loadAllMethod); List <T> elements = listeCache.FindAll(selector); // Si l'élément a été trouvé ou si on ne doit pas relancer la recherche en cas d'absence de l'élément, on retourne la valeur trouvée if ((elements != null && elements.Count > 0) || !forceReloadIfMissing) { return(elements); } // Sinon on marque la collection liée à l'élément comme expirée et on rappelle une fois la recherche MarkAsDirty <T>(); return(GetElements(selector, loadAllMethod, false)); }
/// <summary> /// Renvoie tous les éléments du type passé en generic /// </summary> /// <typeparam name="T">Type à renvoyer</typeparam> /// <param name="loadAllMethod">Methode de chargement si les éléments ne sont pas encore dans le cache</param> /// <returns></returns> public static List <T> GetAll <T>(LoadAllMethod <T> loadAllMethod) where T : class { Type type = typeof(T); // On gère en une seule "transaction" la purge éventuelle, le contrôle de présence et l'extraction, sans quoi des erreurs telles que "clé déjà présente" ou à l'inverse "clé absente" peuvent survenir exceptionnellement, notamment lors des purges pour la seconde erreur. lock (((ICollection)_cache).SyncRoot) { GererExpiration(); if (!_cache.ContainsKey(type)) { List <T> liste = loadAllMethod(); _cache.Add(type, liste); } List <T> listeCache = _cache[type] as List <T>; return(listeCache); } }