- feat: Added memory caching support - feat: refactored dependency injection methods
		
			
				
	
	
		
			87 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Core.Blueprint.Caching.Contracts;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using Microsoft.Extensions.Caching.Memory;
 | |
| using System.Text.Json;
 | |
| 
 | |
| namespace Core.Blueprint.Caching
 | |
| {
 | |
|     public sealed class MemoryCacheProvider : ICacheProvider
 | |
|     {
 | |
|         private readonly IMemoryCache _cache;
 | |
|         private readonly ILogger<MemoryCacheProvider> _logger;
 | |
|         public MemoryCacheProvider(IMemoryCache cache, ILogger<MemoryCacheProvider> logger)
 | |
|         {
 | |
|             _cache = cache;
 | |
|             _logger = logger;
 | |
|         }
 | |
| 
 | |
|         public ValueTask<TEntity> GetAsync<TEntity>(string key)
 | |
|         {
 | |
|             if (_cache.TryGetValue(key, out var value))
 | |
|             {
 | |
|                 if (value is TEntity typedValue)
 | |
|                 {
 | |
|                     return ValueTask.FromResult(typedValue);
 | |
|                 }
 | |
| 
 | |
|                 try
 | |
|                 {
 | |
|                     var json = value?.ToString();
 | |
|                     var deserialized = JsonSerializer.Deserialize<TEntity>(json);
 | |
|                     return ValueTask.FromResult(deserialized);
 | |
|                 }
 | |
|                 catch (Exception ex)
 | |
|                 {
 | |
|                     _logger.LogWarning(ex, "Error deserializing cache value for key {Key}", key);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return ValueTask.FromResult(default(TEntity));
 | |
|         }
 | |
| 
 | |
|         public ValueTask SetAsync<TEntity>(string key, TEntity value, TimeSpan? expiry = null)
 | |
|         {
 | |
|             var options = new MemoryCacheEntryOptions();
 | |
|             if (expiry.HasValue)
 | |
|             {
 | |
|                 options.SetAbsoluteExpiration(expiry.Value);
 | |
|             }
 | |
| 
 | |
|             _cache.Set(key, value, options);
 | |
|             return ValueTask.CompletedTask;
 | |
|         }
 | |
| 
 | |
|         public ValueTask RemoveAsync(string key)
 | |
|         {
 | |
|             _cache.Remove(key);
 | |
|             return ValueTask.CompletedTask;
 | |
|         }
 | |
| 
 | |
|         public ValueTask<bool> ExistsAsync(string key)
 | |
|         {
 | |
|             return ValueTask.FromResult(_cache.TryGetValue(key, out _));
 | |
|         }
 | |
| 
 | |
|         public ValueTask RefreshAsync(string key, TimeSpan? expiry = null)
 | |
|         {
 | |
|             // MemoryCache does not support sliding expiration refresh like Redis,
 | |
|             // so we must re-set the value manually if required.
 | |
| 
 | |
|             if (_cache.TryGetValue(key, out var value))
 | |
|             {
 | |
|                 _cache.Remove(key);
 | |
| 
 | |
|                 var options = new MemoryCacheEntryOptions();
 | |
|                 if (expiry.HasValue)
 | |
|                 {
 | |
|                     options.SetAbsoluteExpiration(expiry.Value);
 | |
|                 }
 | |
| 
 | |
|                 _cache.Set(key, value, options);
 | |
|             }
 | |
| 
 | |
|             return ValueTask.CompletedTask;
 | |
|         }
 | |
|     }
 | |
| }
 |