Introduction
There are a lot of cases where I need to define some sort of a map that I would later want to modify. On my last project, I was working in domain driven development, and I had the necessity to have a mapper class to map my entity to the POCO objects that were exposed through WCF, so I thought about making this simple solution that can make any class mappable to another type even if you just need to map some object's properties to another.
Using the code
First of all, we need to implement a couple of classes that we are going to use in this article:
public class FirstType : GenericMapper<secondtype>
{
public string FirstName { get; set; }
public string Surname { get; set; }
}
public class SecondType
{
public string Name { get; set; }
public string Surname { get; set; }
}
Now, suppose we want to be able to map FirstType
to the second type, and we want to define the mapping using a "friendly" syntax to make the code readable and easy to understand. The solution is the mapper shown below:
Public delegate void MappingRules<d>(D To);
public abstract class GenericMapper<d> where D : new()
{
private D toObj;
public List<MappingRules<D>> MappingRule =
new List<MappingRules<D>>();
public void SetMapping(params MappingRules<d>[] mappingList)
{
MappingRule = mappingList.ToList();
}
public D GetMappedObject()
{
toObj = (D)Activator.CreateInstance(typeof(D));
foreach (var action in MappingRule)
{
action.Invoke(toObj);
}
return toObj;
}
}
I make the mapper class abstract so that it can be used just as the base type. I also defined a generic delegate that will be used to store all the mapping rules. The core of the mapper is the GetMappedObject()
that returns the object we want to be mapped with all the properties already initialized.
It is easier to understand this with an example. In this case, I want to map FirstType
to SecondType
, so I have to make the FirstType
be able to be mapped to SecondType
. I can do this easily by making FirstType
extended from the mapper class. The mapper class is generic so we have to specify the type we want to be returned, in this case, SecondType
.
public class FirstType : GenericMapper<secondtype>
{
public string FirstName { get; set; }
public string Surname { get; set; }
public FirstType()
{
this.SetMapping(x => x.Surname = this.Surname,
x => x.Name = this.FirstName);
}
}
Now all we need is to define a constructor where we specify the mapping between the object using a Lambda Expression: that makes the mapping easy to understand and very readable.
Now, we just need to call GetMappedObjecton
of FirstType
to have SecondType
object already initialized, as we have defined in the constructor.
static void Main(string[] args)
{
FirstType f = new FirstType();
f.FirstName = "Peluso";
f.Surname = "Massimiliano";
SecondType result = f.GetMappedObject();
Console.WriteLine(result.Name);
Console.WriteLine(result.Surname);
}
As shown in this article, this mapper is very flexible, and it can be used wherever we need a mapper between entity objects.