кэш сменен на memoryCache

(стар)
This commit is contained in:
eugeniy_ivanov 2023-02-05 21:53:51 +05:00
parent b70fa35ef6
commit ff12c17496
2 changed files with 104 additions and 24 deletions

View File

@ -43,6 +43,7 @@
<PackageReference Include="itext7" Version="7.2.3" /> <PackageReference Include="itext7" Version="7.2.3" />
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> <PackageReference Include="iTextSharp" Version="5.5.13.3" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.23.1" /> <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.23.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" />

View File

@ -1,9 +1,7 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions; using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudDb;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.EfCache;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
@ -11,6 +9,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
@ -29,10 +28,12 @@ namespace AsbCloudInfrastructure.Repository
dst => dst.Files, dst => dst.Files,
dst => dst.RelationUsersUserRoles) dst => dst.RelationUsersUserRoles)
.Config; .Config;
private readonly IMemoryCache memoryCache;
public UserRepository(IAsbCloudDbContext dbContext, IUserRoleRepository userRoleRepository) { public UserRepository(IAsbCloudDbContext dbContext, IUserRoleRepository userRoleRepository, IMemoryCache memoryCache)
{
this.dbContext = dbContext; this.dbContext = dbContext;
this.userRoleRepository = userRoleRepository; this.userRoleRepository = userRoleRepository;
this.memoryCache = memoryCache;
} }
public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token) public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token)
@ -59,11 +60,12 @@ namespace AsbCloudInfrastructure.Repository
public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token) public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token)
{ {
var dtos = (await GetCacheUserAsync(token)).ToList(); var dtos = (await GetCacheUserAsync(token)).ToList();
var listDtos = dtos.ToList();
if (dtos is null) if (dtos is null)
return Enumerable.Empty<UserExtendedDto>(); return Enumerable.Empty<UserExtendedDto>();
for (var i = 0; i < dtos.Count; i++) for (var i = 0; i < listDtos.Count; i++)
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id); listDtos[i].RoleNames = GetRolesNamesByIdUser(listDtos[i].Id);
return dtos; return dtos;
} }
@ -170,31 +172,43 @@ namespace AsbCloudInfrastructure.Repository
throw new ArgumentInvalidException($"Login {login} is busy by {existingUserDto.MakeDisplayName()}, id{existingUserDto.Id}", nameof(login)); throw new ArgumentInvalidException($"Login {login} is busy by {existingUserDto.MakeDisplayName()}, id{existingUserDto.Id}", nameof(login));
} }
private Task<IEnumerable<UserExtendedDto>> GetCacheUserAsync(CancellationToken token) private async Task<IEnumerable<UserExtendedDto>> GetCacheUserAsync(CancellationToken token)
=> dbContext.Users {
var query = dbContext.Users
.Include(r => r.Company) .Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles) .Include(r => r.RelationUsersUserRoles);
.FromCacheAsync(userCacheTag, cacheObsolence, Convert, token); return await FromCacheAsync(query, userCacheTag, cacheObsolence, Convert, token);
}
private IEnumerable<UserExtendedDto> GetCacheUser() private IEnumerable<UserExtendedDto> GetCacheUser()
=> dbContext.Users {
var query = dbContext.Users
.Include(r => r.Company) .Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles) .Include(r => r.RelationUsersUserRoles);
.FromCache(userCacheTag, cacheObsolence, Convert); return FromCache(query, userCacheTag, cacheObsolence, Convert);
}
private void DropCacheUsers() private void DropCacheUsers()
=> dbContext.Users.DropCache(userCacheTag); {
memoryCache.Remove(userCacheTag);
}
private Task<IEnumerable<RelationUserUserRole>> GetCacheRelationUserUserRoleAsync(CancellationToken token) private async Task<IEnumerable<RelationUserUserRole>> GetCacheRelationUserUserRoleAsync(CancellationToken token)
=> dbContext.RelationUserUserRoles {
var query = dbContext.RelationUserUserRoles
.Include(r => r.UserRole) .Include(r => r.UserRole)
.Include(r => r.User) .Include(r => r.User);
.FromCacheAsync(relationUserUserRoleCacheTag, cacheObsolence, token); return await FromCacheAsync(query, relationUserUserRoleCacheTag, cacheObsolence, token);
}
private IEnumerable<RelationUserUserRole> GetCachRelationUserUserRoleCacheTag() private IEnumerable<RelationUserUserRole> GetCachRelationUserUserRoleCacheTag()
=> dbContext.RelationUserUserRoles {
var query = dbContext.RelationUserUserRoles
.Include(r => r.UserRole) .Include(r => r.UserRole)
.Include(r => r.User) .Include(r => r.User);
.FromCache(relationUserUserRoleCacheTag, cacheObsolence); return FromCache(query, relationUserUserRoleCacheTag, cacheObsolence);
}
private void DropCacheRelationUserUserRoleCacheTag() private void DropCacheRelationUserUserRoleCacheTag()
=> dbContext.RelationUserUserRoles.DropCache(relationUserUserRoleCacheTag); {
memoryCache.Remove(relationUserUserRoleCacheTag);
}
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token) private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token)
{ {
@ -212,6 +226,71 @@ namespace AsbCloudInfrastructure.Repository
DropCacheRelationUserUserRoleCacheTag(); DropCacheRelationUserUserRoleCacheTag();
} }
public async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token)
where TEntity : class
{
async Task<TEntity[]> factory(CancellationToken token)
=> await query.AsNoTracking().ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
return cache.Select(convert);
}
public async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token)
where TEntity : class
{
async Task<TEntity[]> factory(CancellationToken token)
=> await query.AsNoTracking().ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
return cache;
}
public IEnumerable<TModel> FromCache<TEntity, TModel>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert)
where TEntity : class
{
TEntity[] factory()
=> query.AsNoTracking().ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence);
return cache.Select(convert);
}
public IEnumerable<TEntity> FromCache<TEntity>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence)
where TEntity : class
{
TEntity[] factory()
=> query.AsNoTracking().ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence);
return cache;
}
private async Task<TEntity[]> GetOrAddCacheAsync<TEntity>(string tag, Func<CancellationToken, Task<TEntity[]>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
{
memoryCache.TryGetValue(tag, out TEntity[]? cached);
if (cached == null)
{
var values = await valueFactoryAsync(token);
if (values != null)
{
memoryCache.Set(tag, values, new MemoryCacheEntryOptions().SetAbsoluteExpiration(obsolete));
}
return values!;
}
return cached;
}
private TEntity[] GetOrAddCache<TEntity>(string tag, Func<TEntity[]> valueFactory, TimeSpan obsolete)
{
memoryCache.TryGetValue(tag, out TEntity[]? cached);
if (cached == null)
{
var values = valueFactory();
if (values != null)
{
memoryCache.Set(tag, values, new MemoryCacheEntryOptions().SetAbsoluteExpiration(obsolete));
}
return values!;
}
return cached;
}
protected virtual User Convert(UserExtendedDto dto) protected virtual User Convert(UserExtendedDto dto)
{ {
var entity = dto.Adapt<User>(userTypeAdapterConfig); var entity = dto.Adapt<User>(userTypeAdapterConfig);