Search code examples
aspnetboilerplate

How to use caching in ASP.NET Boilerplate?


I have some master data in DB which I need throughout my application. So What is the best way to define this data in the application? and Where should I define in the application so that every time applications starts I will initialize this master data in my application. And Where should I define the method which will fetch data from DB?

using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Runtime.Caching;
using Test.Authorization;
using Test.Caching.Dto;

namespace Test.Caching
{
    [AbpAuthorize(AppPermissions.Pages_Administration_Host_Maintenance)]
    public class CachingAppService : TestAppServiceBase, ICachingAppService
    {
        private readonly ICacheManager _cacheManager;

        public CachingAppService(ICacheManager cacheManager)
        {
            _cacheManager = cacheManager;
        }

        public ListResultDto<CacheDto> GetAllCaches()
        {
            var caches = _cacheManager.GetAllCaches()
                                        .Select(cache => new CacheDto
                                        {
                                            Name = cache.Name
                                        })
                                        .ToList();

            return new ListResultDto<CacheDto>(caches);
        }

        public async Task ClearCache(EntityDto<string> input)
        {
            var cache = _cacheManager.GetCache(input.Id);
            await cache.ClearAsync();
        }

        public async Task ClearAllCaches()
        {
            var caches = _cacheManager.GetAllCaches();
            foreach (var cache in caches)
            {
                await cache.ClearAsync();
            }
        }
    }
}

Startup.cs code:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
   services.AddMemoryCache();
}

Solution

  • This answer is based on the documentation for Entity Caching.

    What is the best way to define this data in the application?

    As a cache item:

    [AutoMapFrom(typeof(Person))]
    public class PersonCacheItem
    {
        public string Name { get; set; }
    }
    

    Where should I define in the application so that every time applications starts I will initialize this master data in my application? How to add my data to cache? Where do I need to add data to cache?

    You don't initialize the master data (nor add data to IEntityCache). It's lazy-loaded.

    Default cache expire time is 60 minutes. It's sliding. So, if you don't use an item in the cache for 60 minutes, it's automatically removed from the cache. You can configure it for all caches or for a specific cache.

    // Configuration for a specific cache
    Configuration.Caching.Configure("MyCache", cache =>
    {
        cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8);
    });
    

    This code should be placed PreInitialize method of your module.

    Where should I define the method which will fetch data from DB?

    You don't define the method. Just inject an IRepository. Specify cacheName if configured above.

    public class PersonCache : EntityCache<Person, PersonCacheItem>, IPersonCache, ITransientDependency
    {
        public PersonCache(ICacheManager cacheManager, IRepository<Person> repository)
            : base(cacheManager, repository, "MyCache") // "MyCache" is optional
        {
        }
    }
    
    public interface IPersonCache : IEntityCache<PersonCacheItem>
    {
    }
    

    How will I get data from cache?

    An example class that uses the Person cache:

    public class MyPersonService : ITransientDependency
    {
        private readonly IPersonCache _personCache;
    
        public MyPersonService(IPersonCache personCache)
        {
            _personCache = personCache;
        }
    
        public string GetPersonNameById(int id)
        {
            return _personCache[id].Name; // alternative: _personCache.Get(id).Name;
        }
    }