I have a couple interfaces (IMapFrom
and IMapTo
) that allow me to simplify my AutoMapper
configurations. Each of the interfaces has a default implementation for the MapTo
and MapFrom
methods. I have a separate MappingProfile
class that uses reflection to find all of the implementing classes, and invokes their map creation.
The aforementioned classes look like so:
public interface IMapFrom<T>
{
void MapFrom(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
public interface IMapTo<T>
{
void MapTo(Profile profile) => profile.CreateMap(GetType(), typeof(T));
}
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<>) ||
i.GetGenericTypeDefinition() == typeof(IMapTo<>))))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var mapTo = type.GetMethod("MapTo");
var mapFrom = type.GetMethod("MapFrom");
mapTo?.Invoke(instance, new object[] {this});
mapFrom?.Invoke(instance, new object[] {this});
}
}
}
If the class implementing the interfaces overrides the default interface implementations, the MappingProfile
class works as desired. However, if the classes simply rely on the default implementations, mapTo
and mapFrom
in the ApplyMappingsFromAssembly
method are both null.
For example, this class would not have its mappings applied successfully:
public class CreateJobCommand :
UpdateJobInputModel,
IMapFrom<UpdateJobInputModel>,
IMapTo<Job>,
IRequest<int>
{
}
How can I get the default implementations if they're not reimplemented in the inheriting class?
Per Kevin Gosse's comment to my question, I looked into using
GetInterface().GetMethod()
as seen in the Microsoft documentation.If I take that approach, the now functional, resulting code looks like: