public static T GetKeyT <TId>(TId id, int decaysec, Func <TId, T> factory) { // Get object from cache and Load/Create it if needed. // NOTE: await Task<T> cant be done inside lock !??? // TId = int or string. // like IMemoryCache GetOrCreate string cacheKey = string.Concat(typeof(T).Name, CacheData.kSep, id); lock (_WeakRefs) { // Find in the hard ref cache first. T obj = (T)CacheData.Get(cacheKey); if (obj != null) { return(obj); // got it. } // Fallback to the weak ref cache next. e.g. someone has a ref that existed longer than the cache? get it. WeakReference wr; if (_WeakRefs.TryGetValue(cacheKey, out wr)) { if (wr.IsAlive) { // someone still has a ref to this . so continue to use it. we should reload this from the db though. obj = (T)wr.Target; } } // lastly load it if we cant find it otherwise. if (factory != null) { // NOTE: await Task<T> cant be done inside lock ! T objLoad = factory.Invoke(id); ValidState.ThrowIfNull(objLoad, nameof(objLoad)); if (obj == null) { obj = objLoad; // Fresh load. if (wr != null) { _WeakRefs.Remove(cacheKey); } _WeakRefs.Add(cacheKey, new WeakReference(obj)); } else { PropertyUtil.InjectProperties <T>(obj, objLoad); // refresh props in old weak ref. } } if (obj != null) { // store it in cache. refresh decaySec. CacheData.Set(cacheKey, obj, decaysec); } return(obj); } }
public static void SetSingleton(T obj, int decaySec = 60 *CacheData.kSecond) { CacheData.Set(typeof(T).Name, obj, decaySec); }
public static void Set(string id, T obj, int decaySec = 60 *CacheData.kSecond) { string cacheKey = MakeKey(id); CacheData.Set(cacheKey, obj, decaySec); }