using AutoMapper; using AutoMapper.Internal; using FaKrosnoEfDataModel.Dtos; using Microsoft.EntityFrameworkCore; using System.Reflection; namespace FaKrosnoEfDataModel.Services { public class ServiceBase 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 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> GetAll() { MethodInfo? setMethod = typeof(DbContext).GetMethod("Set", Array.Empty())?.MakeGenericMethod(EntityType); IQueryable? dbSet = setMethod?.Invoke(Context, null) as IQueryable; if (dbSet == null) { throw new InvalidOperationException("Failed to get DbSet for entity type."); } IList entities = await Task.Run(() => dbSet.Cast().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}"); } } }