Technology with opinion

Wednesday, April 07, 2010

Automatically mapping objects of same derived types

I had a need to automatically map all properties from one class to another class. These two classes had the same derived type, this was by design and not by accident. FYI: this example's Unit Test uses NUnit (2.5), NBuilder, both are optional as the test below can be easily adapted.

The scenario goes like this: you have a base class called BaseTransaction with derived classes DebitTransaction and CreditTransaction. Often where there are many properties from the base class to map, it's redundant to write and tedious. This bit of reflection below iterates through each property of the base class and maps it to a new object that it creates and returns this object.

The following unit test shows the usage of this function, as well as outputs to the console showing that the bases members were in fact mapped. Each derived class has unique properties of the same name (TransactionId), neither of these were mapped - otherwise an exception would have been thrown during the reflection code (prop.SetValue...).

5 comments:

Daniel Severin said...

I think what you can use AutoMapper: http://automapper.codeplex.com

It might be more complex than you need, but I think it can do the job.

Scott White said...

I probably could however I had to support .Net 2.0 and there isn't a 2.0 release for Automapper unfortunately.

Daniel Severin said...

OK, I understand, and i tried the following code targeting .NET 2.0

using System;
using AutoMapper;

class Program
{
class FooBase
{
public string MyProperty { get; set; }
public string MySecondProperty { get; set; }
}

class Boo : FooBase
{
public string FooProperty { get; set; }
}

class Bar : FooBase
{
public string BooProperty { get; set; }
}

static void Main()
{
Boo boo = new Boo();
boo.MyProperty = "some value";
boo.MySecondProperty = "some other value";
boo.FooProperty = "boo property value";
Bar bar = new Bar();
bar.BooProperty = "unchanged bar property";
Mapper.CreateMap<Boo, Bar>();
Mapper.Map(boo, bar);
Console.WriteLine("bar.MyProperty = {0}", bar.MyProperty);
Console.WriteLine("bar.MySecondProperty = {0}", bar.MySecondProperty);
Console.WriteLine("bar.BooProperty = {0}", bar.BooProperty);
}
}

and it worked. It's true that you need .NET greater than 2.0 to use all it's features, but for this kind of tasks I believe is enough.

Scott White said...

I guess I could get the source and do a .Net 2.0 build of Automapper. I may just do that. Thanks for the feedback.

Scott White said...

Since AutoMapper uses a lot of Linq, there it would take a lot of modifications to get it to compile for .Net 2.0.

I won't have this constraint on .Net 2.0 forever. AutoMapper is already in my lib directory for our 3.5 stuff.