#7205798 Перенос сервиса пользователей и ролей в репозиторий

This commit is contained in:
ai.astrakhantsev 2022-11-02 15:04:46 +05:00
parent 2b26f8beb6
commit 36b07eb640
3 changed files with 61 additions and 34 deletions

View File

@ -21,46 +21,74 @@ namespace AsbCloudInfrastructure.EfCache
private static readonly TimeSpan minCacheTime = TimeSpan.FromSeconds(2); private static readonly TimeSpan minCacheTime = TimeSpan.FromSeconds(2);
private static readonly TimeSpan defaultObsolescence = TimeSpan.FromMinutes(4); private static readonly TimeSpan defaultObsolescence = TimeSpan.FromMinutes(4);
private class YeldConvertedData<TEntity, TModel> : IEnumerable<TModel> private class YieldConvertedData<TEntity, TModel> : IEnumerable<TModel>
{ {
IEnumerable data; private struct ConvertedData
public YeldConvertedData(IEnumerable<TEntity> entities, Func<TEntity, TModel> convert)
{ {
data = entities; public TEntity? Entity;
public TModel? Model;
} }
class Enumerator : IEnumerator<TModel> ConvertedData[] data;
{ public Func<TEntity, TModel> convert { get; }
private readonly IEnumerable data;
public Enumerator( IEnumerable data, Func<TEntity, TModel> convert) public YieldConvertedData(TEntity[] entities, Func<TEntity, TModel> convert)
{
data = (entities.Select(x => new ConvertedData {
Entity = x,
Model = default }))
.ToArray();
this.convert = convert;
}
class YieldConvertedDataEnumerator : IEnumerator<TModel>
{
private readonly ConvertedData[] data;
private readonly Func<TEntity, TModel> convert;
private int position = -1;
public YieldConvertedDataEnumerator(ConvertedData[] data, Func<TEntity, TModel> convert)
{ {
this.data = data; this.data = data;
this.convert = convert;
} }
public TModel Current => throw new NotImplementedException(); public TModel Current
{
get
{
if (data[position].Entity is TEntity entity)
{
var dto = convert(entity);
data[position].Entity = default;
data[position].Model = dto;
}
return data[position].Model!;
}
}
object IEnumerator.Current => throw new NotImplementedException(); object IEnumerator.Current => Current!;
public void Dispose() public void Dispose()
{ {
throw new NotImplementedException();
} }
public bool MoveNext() public bool MoveNext()
{ {
throw new NotImplementedException(); position++;
return (position < data.Length);
} }
public void Reset() public void Reset()
{ {
throw new NotImplementedException(); position = -1;
} }
} }
public IEnumerator<TModel> GetEnumerator() public IEnumerator<TModel> GetEnumerator()
{ {
throw new NotImplementedException(); var result = new YieldConvertedDataEnumerator(data, convert);
return result;
} }
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
@ -93,7 +121,7 @@ namespace AsbCloudInfrastructure.EfCache
{ {
try try
{ {
var convertedData = typedEntityData.Select(convert).ToArray(); var convertedData = new YieldConvertedData<TEntity, TModel>(typedEntityData.ToArray(), convert);
Data = convertedData; Data = convertedData;
return convertedData; return convertedData;
} }
@ -111,7 +139,7 @@ namespace AsbCloudInfrastructure.EfCache
else else
{ {
semaphore.Release(); semaphore.Release();
throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while converting cache data"); throw new TimeoutException("EfCacheL2.GetData. Can't wait too long while converting cache data");
} }
} }
} }
@ -121,7 +149,7 @@ namespace AsbCloudInfrastructure.EfCache
} }
} }
private static CacheItem GetOrAddCache(string tag, Func<IEnumerable> valueFactory, TimeSpan obsolete) private static CacheItem GetOrAddCache(string tag, Func<object[]> valueFactory, TimeSpan obsolete)
{ {
CacheItem cache; CacheItem cache;
while (!caches.ContainsKey(tag)) while (!caches.ContainsKey(tag))
@ -194,7 +222,7 @@ namespace AsbCloudInfrastructure.EfCache
return cache; return cache;
} }
private static async Task<CacheItem> GetOrAddCacheAsync(string tag, Func<CancellationToken, Task<IEnumerable>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token) private static async Task<CacheItem> GetOrAddCacheAsync(string tag, Func<CancellationToken, Task<object[]>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
{ {
CacheItem cache; CacheItem cache;
while (!caches.ContainsKey(tag)) while (!caches.ContainsKey(tag))
@ -291,7 +319,7 @@ namespace AsbCloudInfrastructure.EfCache
public static IEnumerable<TEntity> FromCache<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence) public static IEnumerable<TEntity> FromCache<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence)
where TEntity : class where TEntity : class
{ {
IEnumerable factory() => query.AsNoTracking().ToList(); object[] factory() => query.AsNoTracking().ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence); var cache = GetOrAddCache(tag, factory, obsolescence);
return cache.GetData<TEntity>(); return cache.GetData<TEntity>();
} }
@ -310,7 +338,7 @@ namespace AsbCloudInfrastructure.EfCache
public static IEnumerable<TModel> FromCache<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert) public static IEnumerable<TModel> FromCache<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert)
where TEntity : class where TEntity : class
{ {
IEnumerable factory() => query.AsNoTracking().ToList(); object[] factory() => query.AsNoTracking().ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence); var cache = GetOrAddCache(tag, factory, obsolescence);
return cache.GetData(convert); return cache.GetData(convert);
} }
@ -334,8 +362,8 @@ namespace AsbCloudInfrastructure.EfCache
public static async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token = default) public static async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token = default)
where TEntity : class where TEntity : class
{ {
async Task<IEnumerable> factory(CancellationToken token) async Task<object[]> factory(CancellationToken token)
=> await query.AsNoTracking().ToListAsync(token); => await query.AsNoTracking().ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token); var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
return cache.GetData<TEntity>(); return cache.GetData<TEntity>();
} }
@ -355,8 +383,8 @@ namespace AsbCloudInfrastructure.EfCache
public static async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token = default) public static async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token = default)
where TEntity : class where TEntity : class
{ {
async Task<IEnumerable> factory(CancellationToken token) async Task<object[]> factory(CancellationToken token)
=> await query.AsNoTracking().ToListAsync(token); => await query.AsNoTracking().ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token); var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
return cache.GetData(convert); return cache.GetData(convert);
} }

View File

@ -105,7 +105,8 @@ namespace AsbCloudInfrastructure.Repository
public IEnumerable<UserRoleDto> GetNestedById(int id, int recursionLevel = 7) public IEnumerable<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
{ {
var dto = GetCacheUserRole().FirstOrDefault(r => r.Id == id); var dto = GetCacheUserRole()
.FirstOrDefault(r => r.Id == id);
if (dto is null) if (dto is null)
return Enumerable.Empty<UserRoleDto>(); return Enumerable.Empty<UserRoleDto>();
var role = Convert(dto); var role = Convert(dto);
@ -253,7 +254,7 @@ namespace AsbCloudInfrastructure.Repository
.Include(r => r.RelationUserRoleUserRoles) .Include(r => r.RelationUserRoleUserRoles)
.FromCache(userRoleCacheTag, relationCacheObsolence, Convert); .FromCache(userRoleCacheTag, relationCacheObsolence, Convert);
private void DropCacheUserRole() private void DropCacheUserRole()
=> dbContext.RelationUserUserRoles.DropCache(relationUserRoleUserRoleCacheTag); => dbContext.RelationUserUserRoles.DropCache(userRoleCacheTag);
private Task<IEnumerable<RelationUserRoleUserRole>> GetCacheRelationUserRoleUserRoleAsync(CancellationToken token) private Task<IEnumerable<RelationUserRoleUserRole>> GetCacheRelationUserRoleUserRoleAsync(CancellationToken token)
=> dbContext.RelationUserRoleUserRoles => dbContext.RelationUserRoleUserRoles
@ -294,12 +295,10 @@ namespace AsbCloudInfrastructure.Repository
if (entity.RelationUserRoleUserRoles?.Any() == true) if (entity.RelationUserRoleUserRoles?.Any() == true)
{ {
var rolesCache = GetCacheUserRole(); var rolesCache = GetCacheUserRole();
dto.Roles = entity.RelationUserRoleUserRoles.Select(rel => dto.Roles = entity.RelationUserRoleUserRoles
{ .Select(rel => rolesCache
var dto = rolesCache.First(r => r.Id == rel.IdInclude); .First(r => r.Id == rel.IdInclude))
var includedRole = Convert(dto); .ToArray();
return Convert(includedRole);
}).ToArray();
} }
return dto; return dto;
} }

View File

@ -15,7 +15,7 @@ namespace AsbCloudInfrastructure.Services
: base(context) : base(context)
{ {
} }
//TODO: Перенести в сервис "дело скважины"
public async Task<IEnumerable<FileCategoryDto>> GetWellCaseCategoriesAsync(CancellationToken token) public async Task<IEnumerable<FileCategoryDto>> GetWellCaseCategoriesAsync(CancellationToken token)
{ {
var cache = await GetCacheAsync(token) var cache = await GetCacheAsync(token)