Reputation: 2071
I have search results being returned from an API search method and I would like to keep the response content length as short as possible.
I also have AutoMapper set up, and that in itself is all working nicely with various mappings configured in a profile.
One of the properties of a search result could be fairly weighty and I don't want to have to include that data as it is not likely to be always required. So on the search criteria I have added a flag to include this property.
Is there a way to conditionally map a property based on this other external factor?
At the moment, in the map configuration I have told it to ignore the weighty property, and then if the criteria specifies it, I am subsequently mapping another collection and assigning it to the search result.
e.g. In the mapping profile:
this.CreateMap<myModel, myDto>()
.ForMember((dto) => dto.BigCollection,
(opt) => opt.Ignore())
and then in the code:
results.MyDtos = myModels.Select((m) => Mapper.Map<myDto>(m));
if (searchCriteria.IncludeBigCollection)
{
foreach(MyDto myDto in results.MyDtos)
{
// Map the weighty property from the appropriate model.
myDto.BigCollection = ...
}
}
Upvotes: 2
Views: 3421
Reputation: 2820
If you are using Automapper 5.0 then you can use IMappingOperationOptions
and IValueResolver
to pass the values from the method scope to the mapper itself.
Here is an example:
Your Value Resolver:
class YourValueResolver : IValueResolver<YourSourceType, YourBigCollectionType>
{
public YourBigCollectionType Resolve(YourSourceType source, YourBigCollectionType destination, ResolutionContext context)
{
// here you need your check
if((bool)context.Items["IncludeBigCollection"])
{
// then perform your mapping
return mappedCollection;
}
// else return default or empty
return default(YourBigCollectionType);
}
}
Configure your mappings:
new MapperConfiguration(cfg =>
{
cfg.CreateMap<YourSourceType, YourDestinationType>().ForMember(d => d.YourBigCollection, opt => opt.ResolveUsing<YourValueResolver>());
});
And then you can call Map
method like:
mapper.Map<YourDestinationType>(yourSourceObj, opt.Items.Add("IncludeBigCollection", IncludeBigCollectionValue));
IncludeBigCollectionValue
will be passed into value resolver and used according what you wrote in there.
Upvotes: 3