I'm trying to implement some cross-cutting concerns in my application, which uses AutoMapper to map between different DTOs/message objects.
Say I have this:
configuration.Map<MyMessage, MyEvent>()
. MyEvent
implements IEvent
(which is a marker interface with no properties). Is there any way to ask AutoMapper to map a MyMessage
to IEvent
, and have it infer that "oh, I have a mapping MyMessage
to MyEvent
, and MyEvent
implements IEvent
"?
This (invalid) example shows what I want to achieve:
// IEvent is just a marker interface with no properties,
// and is implemented by all of the *Event classes
configuration.CreateMap<MyMessage, MyEvent>();
configuration.CreateMap<MyOtherMessage, MyOtherEvent>();
// etc.
// ... somewhere else in the code ...
public class MyCrossCuttingThing<TMessage>
{
private readonly IMapper _mapper;
// ... code that does stuff ...
public void DoThing(TMessage message)
{
// ... more code ...
var @event = _mapper.Map<IEvent>(message);
// Here I would expect @event to be a MyEvent instance if
// TMessage is MyMessage, for example
}
}
This gives me an exception:
Missing type map configuration or unsupported mapping.
I've tried adding .Include
or .IncludeBase
to the CreateMap
statement, but same result. Is there any way to achieve what I want, or is this simply not a supported use case?
For this simple case you can use As.
CreateMap<MyMessage, IEvent>().As<MyEvent>();
Given that IEvent is a marker interface, you need also the concrete map MyMessage=>MyEvent. If your real case is more complicated, you need Include. The docs.
I figured out a way of achieving what I want:
configuration.CreateMap<MyMessage, MyEvent>();
configuration.CreateMap<MyMessage, IEvent>()
.ConstructUsing((m, c) => c.Mapper.Map<MyMessage, MyEvent>(m));
configuration.CreateMap<MyOtherMessage, MyOtherEvent>();
configuration.CreateMap<MyOtherMessage, IEvent>()
.ConstructUsing((m, c) => c.Mapper.Map<MyOtherMessage, MyOtherEvent>(m));
// etc. - will encapsulate in an extension method
By registering the mappings like this, AutoMapper finds the correct mapper based on the TMessage
type and gives me back an event instance. Just as simple as I'd hoped!
来源:https://stackoverflow.com/questions/45634493/inferring-destination-type-from-interface-with-automapper