using System.Threading.Tasks; using Abp.Domain.Repositories; using Abp.Events.Bus.Entities; using Abp.Events.Bus.Handlers; using Abp.ObjectMapping; using Abp.Runtime.Caching; namespace Abp.Domain.Entities.Caching { public class EntityCache : EntityCache, IEntityCache where TEntity : class, IEntity { public EntityCache( ICacheManager cacheManager, IRepository repository, string cacheName = null) : base( cacheManager, repository, cacheName) { } } public class EntityCache : IEventHandler>, IEntityCache where TEntity : class, IEntity { public TCacheItem this[TPrimaryKey id] { get { return Get(id); } } public string CacheName { get; private set; } public ITypedCache InternalCache { get { return CacheManager.GetCache(CacheName); } } public IObjectMapper ObjectMapper { get; set; } protected ICacheManager CacheManager { get; private set; } protected IRepository Repository { get; private set; } public EntityCache( ICacheManager cacheManager, IRepository repository, string cacheName = null) { Repository = repository; CacheManager = cacheManager; CacheName = cacheName ?? GenerateDefaultCacheName(); ObjectMapper = NullObjectMapper.Instance; } public virtual TCacheItem Get(TPrimaryKey id) { return InternalCache.Get(id, () => GetCacheItemFromDataSource(id)); } public virtual Task GetAsync(TPrimaryKey id) { return InternalCache.GetAsync(id, () => GetCacheItemFromDataSourceAsync(id)); } public virtual void HandleEvent(EntityChangedEventData eventData) { InternalCache.Remove(eventData.Entity.Id); } protected virtual TCacheItem GetCacheItemFromDataSource(TPrimaryKey id) { return MapToCacheItem(GetEntityFromDataSource(id)); } protected virtual async Task GetCacheItemFromDataSourceAsync(TPrimaryKey id) { return MapToCacheItem(await GetEntityFromDataSourceAsync(id)); } protected virtual TEntity GetEntityFromDataSource(TPrimaryKey id) { return Repository.FirstOrDefault(id); } protected virtual Task GetEntityFromDataSourceAsync(TPrimaryKey id) { return Repository.FirstOrDefaultAsync(id); } protected virtual TCacheItem MapToCacheItem(TEntity entity) { if (ObjectMapper is NullObjectMapper) { throw new AbpException( string.Format( "MapToCacheItem method should be overrided or IObjectMapper should be implemented in order to map {0} to {1}", typeof (TEntity), typeof (TCacheItem) ) ); } return ObjectMapper.Map(entity); } protected virtual string GenerateDefaultCacheName() { return GetType().FullName; } public override string ToString() { return string.Format("EntityCache {0}", CacheName); } } }