public ICacheImplementation Select(TimeSpan durationToCacheItemFor, StorageStyle cacheStorageStyle, ExpirationType expirationType) { Ensure.That(durationToCacheItemFor.IsGreaterThanZero(), "durationToCacheItemFor"); return _selectorDelegate(durationToCacheItemFor, cacheStorageStyle, expirationType, _implementations); }
/// <summary> /// This is the method to be supplied to the constructor of /// the base type as the delegate to use for cache selection. /// Selects a cache based on the heuristic of duration to /// store for, followed by the availability of the requested /// caching functionality. This logic serves as a workable /// example, rather than a recommended strategy. For example, /// the fallback case is handled without error or warning. /// Public rather than protected for testing purposes. /// </summary> /// <remarks> /// NOTE: BA; should we throw an exception if the user requests /// a storage strategy that cannot be fulfilled due to /// limitations of the underlying cache? /// NOTE: BA; Potentially have a flag to indicate strictness of /// choice of cache - i.e. does the cache really need to /// support all the desired features, or can we substitute /// them? /// "narrow down choice of caches to those that can be used, /// then choose the enabled one according to priority". /// </remarks> /// <param name = "implementations">Ordered by preference of use /// with highest pref first.</param> public static ICacheImplementation SelectCacheImplementation(TimeSpan durationToCacheItemFor, StorageStyle cacheStorageStyle, ExpirationType cacheExpirationType, Dictionary<string, ICacheImplementation> implementations) { Ensure.That<FriendlyExceptions.ArgumentOutOfRangeException>(durationToCacheItemFor.IsGreaterThanZero(), "durationToCacheFor") .And<FriendlyExceptions.ArgumentNullException>(implementations.IsNotNull(), "implementations") .And<FriendlyExceptions.ArgumentException>(implementations.Count.Is(2), "implementations") .And<MissingCacheImplementationArgumentException>( implementations.ContainsKey(MemcachedImplementationTypeName), "memcached missing") .And<MissingCacheImplementationArgumentException>( implementations.ContainsKey(AspDotNetImplementationTypeName), "asp.net data cache missing"); ICacheImplementation cacheToUse = null; //simply tries to select memcached if an extended caching period is requested //otherwise attempts to fallback to ASP.NET data cache. This might occur because //the caching expiration type is not supported by memcached. if (durationToCacheItemFor >= LongTermBoundary) { if (implementations[MemcachedImplementationTypeName].Supports((cacheExpirationType)) && implementations[MemcachedImplementationTypeName].IsEnabled) cacheToUse = implementations[MemcachedImplementationTypeName]; if (cacheToUse == null && implementations[AspDotNetImplementationTypeName].Supports((cacheExpirationType)) && implementations[AspDotNetImplementationTypeName].IsEnabled) cacheToUse = implementations[AspDotNetImplementationTypeName]; Ensure.That(cacheToUse.IsNotNull(), () => { throw new CacheSelectionException(implementations); }); } else { if (implementations[AspDotNetImplementationTypeName].Supports((cacheExpirationType)) && implementations[AspDotNetImplementationTypeName].IsEnabled) cacheToUse = implementations[AspDotNetImplementationTypeName]; if (cacheToUse == null && implementations[MemcachedImplementationTypeName].Supports((cacheExpirationType)) && implementations[MemcachedImplementationTypeName].IsEnabled) cacheToUse = implementations[MemcachedImplementationTypeName]; Ensure.That(cacheToUse.IsNotNull(), () => { throw new CacheSelectionException(implementations); }); } return cacheToUse; }