74 lines
2.2 KiB
C#
74 lines
2.2 KiB
C#
using AutoMapper;
|
|
using AutoMapper.Internal;
|
|
using FaKrosnoEfDataModel.Dtos;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Reflection;
|
|
|
|
namespace FaKrosnoEfDataModel.Services
|
|
{
|
|
public class ServiceBase<T> where T : DtoBase
|
|
{
|
|
protected readonly FaKrosnoDbContext Context;
|
|
protected readonly IMapper Mapper;
|
|
protected readonly Type EntityType;
|
|
|
|
public ServiceBase(FaKrosnoDbContext context, IMapper mapper)
|
|
{
|
|
Context = context;
|
|
Mapper = mapper;
|
|
EntityType = FindEntityTypeForDto(typeof(T));
|
|
}
|
|
|
|
public virtual async Task<T?> GetById(int id)
|
|
{
|
|
object? entity = await Context.FindAsync(EntityType, id);
|
|
|
|
if (entity != null)
|
|
{
|
|
return (T)Mapper.Map(entity, entity.GetType(), typeof(T));
|
|
}
|
|
|
|
return default;
|
|
}
|
|
|
|
public virtual async Task<IEnumerable<T>> GetAll()
|
|
{
|
|
MethodInfo? setMethod =
|
|
typeof(DbContext).GetMethod("Set", Array.Empty<Type>())?.MakeGenericMethod(EntityType);
|
|
|
|
IQueryable? dbSet = setMethod?.Invoke(Context, null) as IQueryable;
|
|
|
|
if (dbSet == null)
|
|
{
|
|
throw new InvalidOperationException("Failed to get DbSet for entity type.");
|
|
}
|
|
|
|
IList<object> entities = await Task.Run(() => dbSet.Cast<object>().ToListAsync());
|
|
|
|
return entities.Select(e => (T)Mapper.Map(e, e.GetType(), typeof(T)));
|
|
}
|
|
|
|
private Type FindEntityTypeForDto(Type dtoType)
|
|
{
|
|
IGlobalConfiguration? internalApi = Mapper.ConfigurationProvider.Internal();
|
|
|
|
TypeMap map = internalApi.FindTypeMapFor(dtoType, null);
|
|
|
|
if (map != null)
|
|
{
|
|
return map.DestinationType;
|
|
}
|
|
|
|
foreach (var typeMap in internalApi.GetAllTypeMaps())
|
|
{
|
|
if (typeMap.SourceType == dtoType)
|
|
{
|
|
return typeMap.DestinationType;
|
|
}
|
|
}
|
|
|
|
throw new InvalidOperationException($"No mapping found for DTO type: {dtoType.Name}");
|
|
}
|
|
}
|
|
}
|