I have a ASP.Net MVC project running on .NET 4.6.1 Framework. I have recently added Unity.Mvc 5 IoC framework for dependency injection
In order to have flexibility for unit testing and other, I moved my Unity Configuration to a separate class library so that I can call the Unity Register methods from Unit test projects and other as needed.
Here is my high-level solution design.
I would like to use the same class library to implement application cache.
When I installed Unity.Mvc5 from nuget package it added following references (I added some of them manually) :
- Microsoft.Practices.EnterpriseLibrary.Caching 5.0.505.0
- Enterprise Library Shared Library 5.0.505.0
- Microsoft.Practices.ServiceLocation 1.3.0.0
- Microsoft.Practices.Unity 4.0.0.0
- Microsoft.Practices.Unity.Configuration 4.0.0.0
- Microsoft.Practices.Unity.Interception 2.1.505.0
- Microsoft.Practices.Unity.Interception.Configuration 2.1.505.0
- Microsoft.Practices.Unity.RegistrationByConvention 4.0.0.0
I tried few articles to implement Application Block Cache Management so that I can cache data in my Service Implementer layers, but all those documentations are showing code examples which is expecting Unity 2.xxx version.
Here is my Unity Configuration
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<UserManager<User>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<User>, UserStore<User>>(new HierarchicalLifetimeManager());
container.RegisterType<DbContext, OfficeGxDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<IAppSetting, AppSettingService>();
container.RegisterType<ISubscription, SubscriptionService>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
In my AppSettingService.cs
I have get all method
public List<AppSetting> All()
{
using (var context = new MyDbContext())
{
//CachecKeyItem.AppSettingsAll
return context.AppSettings.Where(x => !x.IsDeleted)
.Include(x => x.Module).ToList();
}
}
I want to store this data in cache and reuse it. Similarly do this across all projects I have in my solution and if there is any update
or add
or delete
for any DB records
, I want the cached object to refresh it
so that cached object is always in sync with DB data
I ended up doing something like this
public interface ICacheService
{
T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class;
}
Service Implementor
public class InMemoryCache : ICacheService
{
public T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class
{
if (MemoryCache.Default.Get(cacheKey) is T item) return item;
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(8));
return item;
}
}
use like this
_cacheService.GetOrSet(CachecKeyItem.AppSettingsAll, () => context.AppSettings
.Where(x => !x.IsDeleted)
.Include(x => x.Module).ToList());
Now my question is, when there is any change to data, like add/edit/delete, how do I refresh the cache in most efficient way? I know deleting the key would be one, is there a better way?