VEU.WathBody/3-app/1-lib/Kit.Helpers/Repository/DictionaryRepositoryLazy.cs

97 lines
3.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if NETCOREAPP
using Microsoft.Extensions.Caching.Memory;
#endif
using Kit.Helpers.Cache;
using System;
using System.Collections.Generic;
namespace Kit.Helpers.Repository
{
public abstract class DictionaryRepositoryLazy<TKey, TEntity> : IDictionaryRepository<TKey, TEntity>
where TEntity : IPersistentKey<TKey>
{
private readonly string _cacheKey;
private readonly ICacheProvider _cacheProvider;
#if NETCOREAPP
private readonly MemoryCacheEntryOptions _cacheOptions = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
Priority = CacheItemPriority.Normal
};
#elif NETFRAMEWORK
private readonly CacheSetProperties _cacheOptions = new CacheSetProperties { DurationSeconds = 3600, EnableCaching = true };
#endif
private readonly object _lockObject = new object();
public DictionaryRepositoryLazy(ICacheProvider cacheProvider, string cacheKey)
{
_cacheProvider = cacheProvider;
_cacheKey = cacheKey;
}
// лучше сделать абстрактным
protected abstract IEnumerable<TEntity> GetData();
protected abstract TEntity GetData(TKey key);
public IDictionary<TKey, TEntity> Select()
{
IDictionary<TKey, TEntity> values = null;
if (_cacheKey.IsNullOrEmpty())
{
throw new ArgumentNullException("Не задан ключ кеширования для репозитория: {0}".ApplyFormat(this.GetType().ToString()));
}
lock (_lockObject)
{
if (_cacheProvider.Contains(_cacheKey))
{
values = (IDictionary<TKey, TEntity>)_cacheProvider.GetCacheData(_cacheKey);
return values;
}
IEnumerable<TEntity> data = this.GetData();
values = new Dictionary<TKey, TEntity>();
// добавить обработку дубликатов
foreach (var item in data)
{
TKey key = item.PersistentKey;
if (values.ContainsKey(key))
{
throw new Exception("Элемент с ключом {0} уже добавлен в коллекцию".ApplyFormat(key));
}
values.Add(item.PersistentKey, item);
}
_cacheProvider.SetCacheData(_cacheKey, values, _cacheOptions);
return values;
}
}
public TEntity Get(TKey key)
{
lock (_lockObject)
{
IDictionary<TKey, TEntity> values = this.Select();
if (values.ContainsKey(key))
{
return values[key];
}
TEntity entity = this.GetData(key);
if (entity == null)
{
return default(TEntity);
}
values.Add(key, entity);
_cacheProvider.SetCacheData(_cacheKey, values, _cacheOptions);
return entity;
}
}
public void ClearCache()
{
_cacheProvider.PurgeCacheItems(_cacheKey);
}
}
}