How should I use AutoMapper?

by Mikael Henriksson 13. February 2010 16:12

It is actually really simple and I have to thank my boss, DBA and friend Fridthjof for that. If you ever thought it is difficult to work with a DBA then imagine having one as your boss! *joke*  

He’s a great guy and as a DBA he is actually very understanding and I have been able to use pretty much any tool I want to get the job done as long as I don’t use CamelCase names in the database. Since we are using whatever tools we feel might get us there the quickest/easiest we have gone down different paths where I have spent a bit more time setting things up with NHibernate whereas my colleague has chosen to move quicker initially with LINQ to SQL  and use Fridthjof to do the queries in form of stored procedures for him. It’s worked out great for both of us though for me it took a while longer but yesterday when we where going to synchronize  our works I found that in the other projects he ran in to having to do all the work two times or so because of the different naming standards in the database and C#. I instantly came to think of AutoMapper so I suggested it, helped him set it up for what I needed from him (took a couple of minutes until it was deployed) and I am pretty sure that I will have his eternal gratitude for showing him AutoMapper. Question is how do I setup AutoMapper? Example below:

 

[Test]
public void AutoMapper_configuration_should_be_valid()
{
	Mapper.CreateMap<ContactQuery, ContactInfo>()
		.ForMember(dest => dest.SomeProperty, opt => opt.Ignore());

	Mapper.CreateMap<ContactInfo, ContactQuery>()
		.ForMember(dest => dest.FirstVersionAt, opt => opt.Ignore())
		.ForMember(dest => dest.LastVersionAt, opt => opt.Ignore())
		.ForMember(dest => dest.MaxResult, opt => opt.Ignore());
	
	Mapper.AssertConfigurationIsValid();
}

 

You can of course do much more than this with AutoMapper but it’s a good start the above is a test verifying that the maps I just setup is valid. don’t worry. AutoMapper will tell you exactly what your mapping problems are. This type of mapping should of course not be confused with NHibernate mappings but they are basically the same thing between two objects instead of between one object and one table.

So how do I use this map then?

var contact = new ContactInfo { ContactId = 1 };
var query = Mapper.Map<ContactInfo, ContactQuery>(contact);

So far so good BUT! This is doing the same thing / writing the same code in two places and you should really not repeat yourself. Time to DRY up and place that in a Profile of the project using it. (I know the documentation is blank =:])  That way it’s really easy to add a test for it and reset the test afterwards so that we at least keep the Assertions to just validating the bare minimum.

public class ContactProfile : Profile
{
	protected override void Configure()
	{
		CreateMap<ContactInfo, ContactQuery>()
			.ForMember(dest => dest.FirstVersionAt, opt => opt.Ignore())
			.ForMember(dest => dest.LastVersionAt, opt => opt.Ignore())
			.ForMember(dest => dest.MaxResult, opt => opt.Ignore());

		CreateMap<ContactQuery, ContactInfo>()
			.ForMember(dest => dest.SomeProperty, opt => opt.Ignore());
	}

	protected override string ProfileName
	{
		get { return "Sync"; }
	}
}

Now then a test to prove that my mappings are actually valid. I like to clear everything both before the test and after the test to be sure I only validate the necessary mappings:

[TestFixture]
public class Verify_AutoMapper_mappings_for
{
	[Test]
	public void ContactProfile()
	{
		Mapper.Reset();
		Mapper.AddProfile<ContactProfile>();
		Mapper.AssertConfigurationIsValid();
		Mapper.Reset();
	}
}

Tags: , ,

C# | Testing | AutoMapper

blog comments powered by Disqus