Reputation: 1330
The MapFrom method of AutoMapper has two overloads:
.MapFrom(Expression<Func<object, object>>
and
.MapFrom<TMember>(string)
The first overload can be used like this:
.ForMember(dest => dest.Date, opt => opt.MapFrom(order => order.Customer.DateOfBirth))
I tried the second overload like this:
.ForMember(dest => dest.Date, opt => opt.MapFrom<DateTime>("Order.Customer.DateOfBirth"))
But it does not work when using a property of an association. Who nows how this second overload can be used when using flattening?
I ask this because I look for a way to do the mapping dynamically; for example:
.ForMember(dest => dest.Date, opt => opt.MapFrom<DateTime>(givenPropertyString))
Thanks in advance.
Upvotes: 4
Views: 4875
Reputation: 25039
There are several options to map types dynamically using Automapper.
First of all, Automapper DynamicMap
is supposed to use if the source type is unknown at compile time. It allows to specify only the destination type:
var message = Mapper.DynamicMap<ICreateOrderMessage>(order);
And about your question about MapFrom(string)
- it works exaclty you suggest:
Mapper.CreateMap<UserModel, UserDto>()
.ForMember(dto => dto.FullName, opt => opt.MapFrom<string>("FirstName"));
Probably nested properties like your "Order.Customer.DateOfBirth" just are not supported.
Upvotes: 2
Reputation: 10078
Seems like the MapFrom
overload .MapFrom<TMember>(string)
doesn't work well with nested properties (I might be wrong here). But, for your questions, you can create a custom method to get nested child property value using reflection. And use it to map any property value dynamically with string NestedPropertyName
.
This is the custom method (source of method here)
public static object GetNestedPropertyValue(object obj, string nestedDottedPropertyName)
{
foreach (String part in nestedDottedPropertyName.Split('.'))
{
if (obj == null)
return null;
PropertyInfo info = obj.GetType().GetProperty(part);
if (info == null)
return null;
obj = info.GetValue(obj, null);
}
return obj;
}
And you can use this method in MapFrom
dynamically (for any property), like this
.ForMember(dest => dest.Date,
opt => opt.MapFrom(src => GetNestedPropertyValue(src, "Order.Customer.DateOfBirth")));
Upvotes: 4