Generic Mapper<TSource, TDest>

Dec 22, 2009 at 11:07 PM
Edited Dec 23, 2009 at 5:36 PM

I found this class useful for cutting down repetative MapFrom() methods.  I also added a MapInto() method since it is often useful to map value into an existing entity (with proper session usage nHibernate will detect if anything has changed after mapping and if not it will do nothing with .Save is called)

 

	public abstract class Mapper<TSource, TDest> : IMapper<TSource, TDest> {
		public virtual TDest MapFrom(TSource source) {
			return Mapper.Map<TSource, TDest>(source);
		}
		public virtual void MapInto(TSource source, TDest dest) {
			Mapper.Map(source, dest);
		}
	}

 

When you ViewModel returns data from the user on an Update the MapInto function can be used to make sure that it only saves if changes have been made.

An implemented class of mine looks like this:

 

	public class SecurityRootMapper : Mapper<SecurityRoot, Security>, ISecurityRootMapper {
		public SecurityRootMapper() {
			Mapper.CreateMap<SecurityRoot, Security>()
				.ForMember(x => x.Bond, c => c.Ignore())
				.ForMember(x => x.Prices, c => c.Ignore())
				.ForMember(x => x.Units, c => c.Ignore())
				.ForMember(x => x.Dividend, c => c.Ignore())
				.ForMember(x => x.Id, c => c.Ignore());
		}
	} 

 

This is actually for mapping a message from a proprietary data file format into a domain entity, so no ViewModels are involved but the idea is the same.  I use it with nhibernate here:

 

		public void LoadSecurityData(){
			foreach (var root in _securityRoots.GetEntities()){
				var security = _securityRepository.FindOne(x => x.IBMSecurityNumber == root.IBMSecurityNumber && x.ISIN == root.ISIN) ?? new Security();
				_securityRootMapper.MapInto(root,security);
				_securityRepository.Save(security);
			}
		}

 

If the security exists it will map any fields that are different in the message but the Id remains the same.  If it doesn't it just creates a new Security entity first.

Chris

Coordinator
Dec 28, 2009 at 11:03 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 14, 2010 at 4:58 AM

Chris, thank you very much for sharing the base mapper implementation. It is indeed helpful to cut down on repetitive IMapper implementations. I wasn't convinced of it's utility until I actually started working in detail with the controller/view layer in my app.

Howard, thank you for adding this to the codebase!

 

Best regards,

Martin