Hello guys,
We have a huge project using AutoMapper 2.x with static scope, and we are on a refactoring time and one of the itens on our backlog is to update AutoMapper to the last version (5.2). We saw that the static scope still exists (we want to keep it) and it is difficult to change now! :(
In the AutoMapper 2.0, we have an extension method called IgnoreAllNonExisting, which just add a Ignore statement on the properties in the TSource that does not exists in the TDestionation. Look the code:
public static IMappingExpression<TSource, TDestination>IgnoreAllNonExisting<TSource, TDestination>
(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var existingMaps = Mapper.Configuration.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
foreach (var property in existingMaps.GetUnmappedPropertyNames())
expression.ForMember(property, opt => opt.Ignore());
return expression;
}
the problem is that the _Mapper.Configuration_ throws an exception when the program hits it:
"Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance."
Then, following some instructions on another threads, I try to modify this method to this:
public static IMappingExpression<TSource, TDestination>IgnoreAllNonExisting<TSource, TDestination>
(this IMappingExpression<TSource, TDestination> expression)
{
expression.ForAllOtherMembers(x => x.Ignore());
return expression;
}
But this method just add the default value for each property on the destination result, making the destination result object get like an empty object with all null properties and 0 (for numbers).
My question: is there any new way to implement this method to ignore properties that does not exists in the TDestination? Maybe a native method? Or how can I fix the existent method?
Thank you
PS: Help/Save us Jimmy :( haha
Yeah keep that static stuff. And this seems to be a very popular post from Stack Overflow that describes a wrong way to do things.
What you really want to do is either:
This "IgnoreAllNonExisting" was a hack pretty much, so instead I have the ability to tell AutoMapper which list of members you want to validate against. That's the intent of IgnoreAllNonExisting anyway. So just get rid of that extension method, and everywhere it's being used, I'd pass in to CreateMap, "MemberList.None".
I've tried to up vote this on SO:
Can this be closed then?
Thank you Jimmy, it is working fine as expected. I will remove this extension method from my project :D
I updated the 5.0 upgrade guide for this specific scenario, hope that helps the next person!
Is there a way to use cfg.CreateMissingTypeMaps = true; and telling the mapper to ignore missing destination properties? I know the default behavior ignores them but I don't want to get errors when I call
Mapper.Configuration.AssertConfigurationIsValid();
.
Is there any way to configure this approach on a TypeConverter class that used by a Profile? at the end, the TypeConverter has the access to all the properties of the source, destination, and the context
Hi, just put [AutoMapper.IgnoreMap()] at the top of that destination property
For the past few hours of going down this rabbit hole, I realized that there's a strong and misunderstood term between the words "ignore" and "validate". I'm not sure why the answer has been accepted for the term "validate", when it's not really ignoring anything. When I tried the validating method, it overwrote all the unmapped properties that I wanted to ignore with nulls and 0s, when all I wanted was to overwrite only the mapped properties. When thinking of the term "validate", you make the assumption of ensuring that certain properties exist otherwise it should fail.
Another problem is that when you use the solution for "ReverseMap()" or including the MemberList method for "CreateMap()", this doesn't give an explicit representation that you'd want to validate certain properties. It'd probably be better to chain the method for CreateMap() and use something like CreateMap().Validate(true, Source), CreateMap().Validate(true, Destination), CreateMap().Validate(false). It just seems more readable that way.
@cloudybrain I think this was for some historical reasons that I needed to put the direction immediately when you called CreateMap. I agree though, it should be consistent with the rest of the API and be a fluent method.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Yeah keep that static stuff. And this seems to be a very popular post from Stack Overflow that describes a wrong way to do things.
What you really want to do is either:
This "IgnoreAllNonExisting" was a hack pretty much, so instead I have the ability to tell AutoMapper which list of members you want to validate against. That's the intent of IgnoreAllNonExisting anyway. So just get rid of that extension method, and everywhere it's being used, I'd pass in to CreateMap, "MemberList.None".