I'm trying to add automapping models with reflection, I created an interface IMapFrom<>
and implemented it in all dtos.
Then I created class
public class MappingProfile : Profile
{
public MappingProfile(Assembly assembly)
=> ApplyMappingsFromAssembly(assembly);
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly
.GetExportedTypes()
.Where(t => t
.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
const string mappingMethodName = "Mapping";
var methodInfo = type.GetMethod(mappingMethodName)
?? type.GetInterface("IMapFrom`1")?.GetMethod(mappingMethodName);
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
And add it in service collection
public static IServiceCollection AddAutoMapperProfile(IServiceCollection services, Assembly assembly)
=> services
.AddAutoMapper(
(_, config) => config
.AddProfile(new MappingProfile(Assembly.GetCallingAssembly())),
Array.Empty<Assembly>());
Why the class instance is not created? Because of this I can't convert the model into a dto
CodePudding user response:
Try like this:
Define IMapFrom:
public interface IMapFrom<T>
{
void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
Then add Mapping profile:
public class MappingProfile : Profile
{
public MappingProfile()
{
ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
}
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly.GetExportedTypes()
.Where(t => t.GetInterfaces().Any(i =>
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping")
?? type.GetInterface("IMapFrom`1")?.GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
Create DI method:
public static IServiceCollection AddAutoMapperProfile(this IServiceCollection services)
{
var assembly = Assembly.GetExecutingAssembly();
services.AddAutoMapper(assembly);
return services;
}
and at the end call DI method that you created:
...
services.AddAutoMapperProfile();
...