Feature/generic cached decorator (#604)

* make TODO: Make a generic decorator for any LookupData type

* remove useless GetById in ICatalogLookupDataService
This commit is contained in:
Cédric Michel
2021-10-31 19:54:00 +01:00
committed by GitHub
parent ed63faac84
commit 68beb21f07
6 changed files with 55 additions and 123 deletions

View File

@@ -1,59 +0,0 @@
using Blazored.LocalStorage;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CachedCatalogBrandServiceDecorator : ICatalogLookupDataService<CatalogBrand>
{
// TODO: Make a generic decorator for any LookupData type
private readonly ILocalStorageService _localStorageService;
private readonly CatalogLookupDataService<CatalogBrand, CatalogBrandResponse> _catalogBrandService;
private ILogger<CachedCatalogBrandServiceDecorator> _logger;
public CachedCatalogBrandServiceDecorator(ILocalStorageService localStorageService,
CatalogLookupDataService<CatalogBrand, CatalogBrandResponse> catalogBrandService,
ILogger<CachedCatalogBrandServiceDecorator> logger)
{
_localStorageService = localStorageService;
_catalogBrandService = catalogBrandService;
_logger = logger;
}
public async Task<CatalogBrand> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<CatalogBrand>> List()
{
string key = "brands";
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogBrand>>>(key);
if (cacheEntry != null)
{
_logger.LogInformation("Loading brands from local storage.");
// TODO: Get Default Cache Duration from Config
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow)
{
return cacheEntry.Value;
}
else
{
_logger.LogInformation("Cache expired; removing brands from local storage.");
await _localStorageService.RemoveItemAsync(key);
}
}
var brands = await _catalogBrandService.List();
var entry = new CacheEntry<List<CatalogBrand>>(brands);
await _localStorageService.SetItemAsync(key, entry);
return brands;
}
}
}

View File

@@ -0,0 +1,53 @@
using Blazored.LocalStorage;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CachedCatalogLookupDataServiceDecorator<TLookupData, TReponse>
: ICatalogLookupDataService<TLookupData>
where TLookupData : LookupData
where TReponse : ILookupDataResponse<TLookupData>
{
private readonly ILocalStorageService _localStorageService;
private readonly CatalogLookupDataService<TLookupData, TReponse> _catalogTypeService;
private ILogger<CachedCatalogLookupDataServiceDecorator<TLookupData, TReponse>> _logger;
public CachedCatalogLookupDataServiceDecorator(ILocalStorageService localStorageService,
CatalogLookupDataService<TLookupData, TReponse> catalogTypeService,
ILogger<CachedCatalogLookupDataServiceDecorator<TLookupData, TReponse>> logger)
{
_localStorageService = localStorageService;
_catalogTypeService = catalogTypeService;
_logger = logger;
}
public async Task<List<TLookupData>> List()
{
string key = typeof(TLookupData).Name;
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<TLookupData>>>(key);
if (cacheEntry != null)
{
_logger.LogInformation($"Loading {key} from local storage.");
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow)
{
return cacheEntry.Value;
}
else
{
_logger.LogInformation($"Cache expired; removing {key} from local storage.");
await _localStorageService.RemoveItemAsync(key);
}
}
var types = await _catalogTypeService.List();
var entry = new CacheEntry<List<TLookupData>>(types);
await _localStorageService.SetItemAsync(key, entry);
return types;
}
}
}

View File

@@ -1,56 +0,0 @@
using Blazored.LocalStorage;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CachedCatalogTypeServiceDecorator : ICatalogLookupDataService<CatalogType>
{
private readonly ILocalStorageService _localStorageService;
private readonly CatalogLookupDataService<CatalogType, CatalogTypeResponse> _catalogTypeService;
private ILogger<CachedCatalogTypeServiceDecorator> _logger;
public CachedCatalogTypeServiceDecorator(ILocalStorageService localStorageService,
CatalogLookupDataService<CatalogType, CatalogTypeResponse> catalogTypeService,
ILogger<CachedCatalogTypeServiceDecorator> logger)
{
_localStorageService = localStorageService;
_catalogTypeService = catalogTypeService;
_logger = logger;
}
public async Task<CatalogType> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<CatalogType>> List()
{
string key = "types";
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogType>>>(key);
if (cacheEntry != null)
{
_logger.LogInformation("Loading types from local storage.");
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow)
{
return cacheEntry.Value;
}
else
{
_logger.LogInformation("Cache expired; removing types from local storage.");
await _localStorageService.RemoveItemAsync(key);
}
}
var types = await _catalogTypeService.List();
var entry = new CacheEntry<List<CatalogType>>(types);
await _localStorageService.SetItemAsync(key, entry);
return types;
}
}
}

View File

@@ -31,11 +31,6 @@ namespace BlazorAdmin.Services
_apiUrl = baseUrlConfiguration.ApiBase; _apiUrl = baseUrlConfiguration.ApiBase;
} }
public async Task<TLookupData> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<TLookupData>> List() public async Task<List<TLookupData>> List()
{ {
var endpointName = typeof(TLookupData).GetCustomAttribute<EndpointAttribute>().Name; var endpointName = typeof(TLookupData).GetCustomAttribute<EndpointAttribute>().Name;

View File

@@ -9,9 +9,9 @@ namespace BlazorAdmin
{ {
public static IServiceCollection AddBlazorServices(this IServiceCollection services) public static IServiceCollection AddBlazorServices(this IServiceCollection services)
{ {
services.AddScoped<ICatalogLookupDataService<CatalogBrand>, CachedCatalogBrandServiceDecorator>(); services.AddScoped<ICatalogLookupDataService<CatalogBrand>, CachedCatalogLookupDataServiceDecorator<CatalogBrand,CatalogBrandResponse>>();
services.AddScoped<CatalogLookupDataService<CatalogBrand, CatalogBrandResponse>>(); services.AddScoped<CatalogLookupDataService<CatalogBrand, CatalogBrandResponse>>();
services.AddScoped<ICatalogLookupDataService<CatalogType>, CachedCatalogTypeServiceDecorator>(); services.AddScoped<ICatalogLookupDataService<CatalogType>, CachedCatalogLookupDataServiceDecorator<CatalogType,CatalogTypeResponse>>();
services.AddScoped<CatalogLookupDataService<CatalogType, CatalogTypeResponse>>(); services.AddScoped<CatalogLookupDataService<CatalogType, CatalogTypeResponse>>();
services.AddScoped<ICatalogItemService, CachedCatalogItemServiceDecorator>(); services.AddScoped<ICatalogItemService, CachedCatalogItemServiceDecorator>();
services.AddScoped<CatalogItemService>(); services.AddScoped<CatalogItemService>();

View File

@@ -7,6 +7,5 @@ namespace BlazorShared.Interfaces
public interface ICatalogLookupDataService<TLookupData> where TLookupData : LookupData public interface ICatalogLookupDataService<TLookupData> where TLookupData : LookupData
{ {
Task<List<TLookupData>> List(); Task<List<TLookupData>> List();
Task<TLookupData> GetById(int id);
} }
} }