You could use a Tuple
for this:
Mapper.CreateMap<Tuple<People, Phone>, PeoplePhoneDto>()
.ForMember(d => d.FirstName, opt => opt.MapFrom(s => s.Item1.FirstName))
.ForMember(d => d.LastName, opt => opt.MapFrom(s => s.Item1.LastName))
.ForMember(d => d.Number, opt => opt.MapFrom(s => s.Item2.Number ));
In case you would have more source models you can use a different representation (List, Dictionary or something else) that will gather all these models together as a source.
The above code should preferaby be placed in some AutoMapperConfiguration file, set once and globally and then used when applicable.
AutoMapper by default supports only a single data source. So there is no possibility to set directly multiple sources (without wrapping it up in a collection) because then how would we know what in case if for example two source models have properties with the same names?
There is though some workaround to achieve this:
public static class EntityMapper
{
public static T Map<T>(params object[] sources) where T : class
{
if (!sources.Any())
{
return default(T);
}
var initialSource = sources[0];
var mappingResult = Map<T>(initialSource);
// Now map the remaining source objects
if (sources.Count() > 1)
{
Map(mappingResult, sources.Skip(1).ToArray());
}
return mappingResult;
}
private static void Map(object destination, params object[] sources)
{
if (!sources.Any())
{
return;
}
var destinationType = destination.GetType();
foreach (var source in sources)
{
var sourceType = source.GetType();
Mapper.Map(source, destination, sourceType, destinationType);
}
}
private static T Map<T>(object source) where T : class
{
var destinationType = typeof(T);
var sourceType = source.GetType();
var mappingResult = Mapper.Map(source, sourceType, destinationType);
return mappingResult as T;
}
}
And then:
var peoplePhoneDto = EntityMapper.Map<PeoplePhoneDto>(people, phone);
But to be quite honest, even though I am using AutoMapper for already a few years I have never had a need to use mapping from multiple sources.
In cases when for example I needed multiple business models in my single view model I simply embedded these models within the view model class.
So in your case it would look like this:
public class PeoplePhoneDto {
public People People { get; set; }
public Phone Phone { get; set; }
}
PeoplePhoneDto
have aPeople
andPhone
member? – Skateboard