If you have not yet had the opportunity to use Jimmy Bogards AutoMapper yet for data transfer mappings between objects, it is truly a great simple way to convert between your DTO’s. Essentially it automatically maps everything from one .NET object to another .NET object based on a set of conventions, or if your customize it, some custom business logic.
Check it out before you continue: https://github.com/AutoMapper/AutoMapper
When specifying the mapping creation between two objects you have two possible approaches that are often used interchangeably by some without understanding the difference:
Mapper.CreateMap<SourceType, DestType>().ForMember(d => d.DestPropX, o => o.ResolveUsing(s => s.SourcePropY));
Mapper.CreateMap<SourceType, DestType>().ForMember(d => d.DestPropX, o => o.MapFrom(s => s.SourcePropY));
In 90% of the time, these are going to and do the exact same thing, and you won’t have to worry. However, if you are doing a more complex flattening exercise for a property that won’t flatten by convention the “MapFrom” includes NULL checks all the way through the object graph. For example:
ForMember(d => d.DestPropX, o => o.MapFrom(s => s.Person.Address.State));
This scenario will not blow up your application if Person or Address is NULL, but instead NULL will be mapped over to the DestPropX safely. AutoMapper automatically catches the thrown NULL reference exception and hides it from you. That sounds AWESOME. But you need to be aware of the overhead price you pay in performance for using Exceptions during your normal workflow of your application.
Consider the scenario where I have a list of 1,000 objects to convert, all with a NULL Person property, in which cases we are looking at 1,000 Null reference exceptions that must be eatin’ inside your app. In my own experience, under the wrong scenario where this was multiplied many times, I had a single web service call that took about 10 sec. Upon investigating, I found that due to the number of exceptions thrown for NULL checks, my web service transformation was taking an extra 5 sec. I could easily get my 50% performance boost by doing some manual NULL checks with ResolveUsing:
ForMember(d => d.DestPropX, o => o.ResolveUsing(s => s.Person != null ? s.Person.Address.State : null ));
By manually doing my null checks, I have avoided the onslaught of exceptions, and get the large performance boost.
While that is one large workflow difference, often the ResolvingUsing is used for custom logic that occurs during the mapping, while the MapFrom is generally reserved for flattening operations. If you expect to never have a null, then you may consider using ResolveUsing in order to get an exception that bubbles up when it occurs, and lets you know there is likely a problem. This way the problem is not hidden from you with the large performance hit on the side.