Last active
November 27, 2019 17:59
-
-
Save danielDevelops/cccd672de9f3b95a4d62b359a5dbd4f6 to your computer and use it in GitHub Desktop.
.Net Caching Engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CommonInterfaces.Infrastructure; | |
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Cache | |
{ | |
public class CacheContainer : ICacheContainer | |
{ | |
readonly ConcurrentDictionary<string, IData<dynamic>> _cache = new ConcurrentDictionary<string, IData<dynamic>>(); | |
public void AddItemToCache<T>(string cacheName, | |
T data, | |
Func<ICustomContext, Task<T>> reloadMethodAsync, | |
bool forceImmediateReload = false, | |
int timeoutInMinutes = 10) where T : class | |
{ | |
if (timeoutInMinutes < 1) | |
throw new InvalidOperationException("You cannot set a cache timeout of less than one minute!!!!"); | |
Func<ICustomContext, Task<dynamic>> reload = async (ICustomContext ctx) => await reloadMethodAsync(ctx); | |
IData<dynamic> cacheItem = new Data<dynamic>(data, reload, new TimeSpan(0, timeoutInMinutes, 0)); | |
_cache.TryAdd(cacheName,cacheItem); | |
} | |
public async Task<T> GetItemFromCache<T>(ICustomContext context, | |
string cacheName, | |
bool forceImmediateReload = false) where T : class | |
{ | |
if (!_cache.TryGetValue(cacheName, out IData<dynamic> cachedDataObject)) | |
return null; | |
var value = await cachedDataObject.GetAsync(context, forceImmediateReload); | |
return value; | |
} | |
public async Task<T> GetAndLoadCacheItemAsync<T>(ICustomContext context, | |
string cacheName, | |
Func<ICustomContext, Task<T>> reloadMethodAsync, | |
bool forceImmediateReload = false, | |
int timeoutInMinutes = 10) where T : class | |
{ | |
if (_cache.TryGetValue(cacheName, out IData<dynamic> cachedDataObject)) | |
{ | |
return await cachedDataObject.GetAsync(context, forceImmediateReload); | |
} | |
var data = await reloadMethodAsync(context); | |
AddItemToCache(cacheName, data, reloadMethodAsync, forceImmediateReload, timeoutInMinutes); | |
return data; | |
} | |
public async Task ReloadCacheAsync(ICustomContext context) | |
{ | |
foreach (var item in _cache) | |
{ | |
await item.Value.ReloadDataAsync(context); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CommonInterfaces.Infrastructure; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Cache | |
{ | |
internal class Data<T> : IData<T> where T : class | |
{ | |
readonly Func<ICustomContext, Task<T>> _reloadMethodAsync; | |
readonly TimeSpan _cacheTimeout; | |
T _cachedData = null; | |
public Data(T data, Func<ICustomContext, Task<T>> reloadMethodAsync, TimeSpan cacheTimeout) | |
{ | |
_cachedData = data; | |
_cacheTimeout = cacheTimeout; | |
_reloadMethodAsync = reloadMethodAsync; | |
} | |
public DateTime Updated { get; private set; } = DateTime.Now; | |
public bool IsExpired => Updated.Add(_cacheTimeout) < DateTime.Now; | |
public async Task ReloadDataAsync(ICustomContext context) | |
{ | |
_cachedData = await _reloadMethodAsync(context ); | |
Updated = DateTime.Now; | |
} | |
public async Task<T> GetAsync(ICustomContext context, bool forceReload = false) | |
{ | |
if (IsExpired || forceReload) | |
await ReloadDataAsync(context); | |
return _cachedData; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CommonInterfaces.Infrastructure; | |
using System; | |
using System.Threading.Tasks; | |
namespace Cache | |
{ | |
public interface ICacheContainer | |
{ | |
void AddItemToCache<T>(string cacheName, | |
T data, | |
Func<ICustomContext, Task<T>> reloadMethodAsync, | |
bool forceImmediateReload, | |
int timeoutInMinutes = 10) where T : class; | |
Task<T> GetAndLoadCacheItemAsync<T>(ICustomContext context, | |
string cacheName, | |
Func<ICustomContext, Task<T>> reloadMethodAsync, | |
bool forceImmediateReload = false, | |
int timeoutInMinutes = 10) where T : class; | |
Task<T> GetItemFromCache<T>(ICustomContext context, | |
string cacheName, | |
bool forceImmediateReload = false) where T : class; | |
Task ReloadCacheAsync(ICustomContext context); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.ChangeTracking; | |
using Microsoft.EntityFrameworkCore.Metadata; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.EntityFrameworkCore.Infrastructure; | |
using System.Threading; | |
namespace CommonInterfaces.Infrastructure | |
{ | |
public interface ICustomContext : IDisposable | |
{ | |
DbSet<TEntity> Set<TEntity>() where TEntity : class; | |
IModel Model { get; } | |
ChangeTracker ChangeTracker { get; } | |
EntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class; | |
DatabaseFacade Database { get; } | |
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default); | |
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default); | |
Task BulkInsertAsync<TEntity>(IList<TEntity> entities) where TEntity : class; | |
bool IsDisposed { get; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CommonInterfaces.Infrastructure; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Cache | |
{ | |
public interface IData<T> | |
{ | |
Task<T> GetAsync(ICustomContext context, bool forceReload = false); | |
Task ReloadDataAsync(ICustomContext context); | |
DateTime Updated { get; } | |
bool IsExpired { get; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.EntityFrameworkCore; | |
using System; | |
using System.Collections.Generic; | |
using System.Data.SqlClient; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace CommonInterfaces.Infrastructure | |
{ | |
public interface IGenericRepository<T> where T: class, new() | |
{ | |
T Insert(T entity, string createdBy); | |
Task<IEnumerable<T>> BulkInsertAsync(IEnumerable<T> entites, string createdBy); | |
Task<T> GetByIDAsync(object id); | |
Task<IEnumerable<T>> GetAsync( | |
Expression<Func<T, bool>> filter = null, | |
IEnumerable<Expression<Func<T, object>>> includeProperties = null, | |
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, | |
int skip = 0, | |
int? take = default(int?), | |
bool disableCacheForQueryPlan = false); | |
IQueryable<T> GetQueryable( | |
Expression<Func<T, bool>> filter = null, | |
IEnumerable<Expression<Func<T, object>>> includeProperties = null, | |
bool disableCacheForQueryPlan = false); | |
void Update(T entity, string modifiedBy, params Expression<Func<T, object>>[] changedProperties); | |
void Delete(T entityToDelete); | |
void Delete(object id); | |
Task ExecuteStoredProcedureAsync(string sql, int timeoutInSeconds = 30, params object[] parameters); | |
Task<IEnumerable<TT>> ExecuteStoredProcedureAsync<TT>(string sql, int timeoutInSeconds = 30, params SqlParameter[] parameters) where TT : class, new(); | |
Task<IEnumerable<TT>> ExecuteDynamicStoredProcedureAsync<TT>(string sprocName, int timeoutInSeconds = 30, params object[] parameterObjects) where TT : class, new(); | |
Task ExecuteSQLAsync(string sql, int timeoutInSeconds = 30); | |
Task TruncateAsync(); | |
void Save(); | |
Task SaveAsync(); | |
T CreateDetachedEntity(T entity); | |
void Detach(T entity); | |
void Attach(T entity); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment