I have two entities: Order & OrderDTO And I'm using AutoMapper to map them together.
Based on some conditions I want these entities to be mapped differently.
In fact I want two or more different mapping rules (CreateMap
) for these entities.
And When calling Map
function I want to tell the engine which mapping rule to use.
Thanks to this question: Using the instance version of CreateMap and Map with a WCF service? one approach is using a different instance of mapper so each one can has it's own mapping rules:
var configuration = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());
var mapper = new MappingEngine(configuration);
configuration.CreateMap<Dto.Ticket, Entities.Ticket>()
Do you have any better solution?
As mentioned by Jimmy Bogard (Creator of AutoMapper) here: Using Profiles in Automapper to map the same types with different logic :
You're better off creating separate Configuration objects, and creating a separate MappingEngine for each. The Mapper class is merely a static facade over each of those, with some lifecycle management.
What lifecycle management is needed to be done?
AutoMapper will map property with private setter with no problem. If you want to force encapsulation, you need to use IgnoreAllPropertiesWithAnInaccessibleSetter.
Your configuration (e.g. Automapper Profiles) are singletons. That is, they are only ever loaded once when your project runs. This makes sense since your configurations will not change while the application is running.
I've ended up creating a new instance of mapper and caching them in a shared(static) concurrent dictionary.
here s my code (vb.net):
mapper factory:
Public Function CreateMapper() As IMapper Implements IMapperFactory.CreateMapper
Dim nestedConfig = New ConfigurationStore(New TypeMapFactory, MapperRegistry.Mappers)
Dim nestedMapper = New MappingEngine(nestedConfig)
Return New AutomapperMapper(nestedConfig, nestedMapper)
End Function
different profiles for different scenarios:
Private Shared _mapperInstances As New Concurrent.ConcurrentDictionary(Of String, IMapper)
Public Shared ReadOnly Property Profile(profileName As String) As IMapper
Get
Return _mapperInstances.GetOrAdd(profileName, Function() _mapperFactory.CreateMapper)
End Get
End Property
and the mapper class:
Friend Class AutomapperMapper
Implements IMapper
Private _configuration As ConfigurationStore
Private _mapper As MappingEngine
Public Sub New()
_configuration = AutoMapper.Mapper.Configuration
_mapper = AutoMapper.Mapper.Engine
End Sub
Public Sub New(configuration As ConfigurationStore, mapper As MappingEngine)
_configuration = configuration
_mapper = mapper
End Sub
Public Sub CreateMap(Of TSource, TDestination)() Implements IMapper.CreateMap
_configuration.CreateMap(Of TSource, TDestination)()
End Sub
Public Function Map(Of TSource, TDestination)(source As TSource, destination As TDestination) As TDestination Implements IMapper.Map
Return _mapper.Map(Of TSource, TDestination)(source, destination)
End Function
Public Function Map(Of TSource, TDestination)(source As TSource) As TDestination Implements IMapper.Map
Return _mapper.Map(Of TSource, TDestination)(source)
End Function
End Class
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With