Click here to Skip to main content
15,883,883 members
Articles / Programming Languages / C# 4.0

Generic Mapper

Rate me:
Please Sign up or sign in to vote.
2.88/5 (5 votes)
28 Feb 2010CPOL2 min read 30.1K   163   9   7
This article show an easy and reusable solution to create a generic mapper between two entity objects.

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:

C#
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:

C#
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.

C#
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.

C#
static void Main(string[] args)
{
    FirstType f = new FirstType();
    f.FirstName = "Peluso";
    f.Surname = "Massimiliano";
    // result is gonna be a secondType object already
    // initialized as we defined into the FirstType contructor.
    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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect PeluSoft Limited
United Kingdom United Kingdom
I have been fascinated by software development since I was 10 years old. I'm proud of learned the first programming language with an Olivetti PC 128S based on Microsoft BASIC. I'm a Software Architect/Senior Developer with a strong background of all the developing Microsoft's technologies.

Comments and Discussions

 
GeneralGeneric Type Mapping Pin
Dave Sexton18-Dec-10 13:03
Dave Sexton18-Dec-10 13:03 
GeneralMy vote of 5 Pin
steliodibello8-Dec-10 11:41
steliodibello8-Dec-10 11:41 
GeneralMy vote of 1 Pin
Yang Yu1-Mar-10 3:43
Yang Yu1-Mar-10 3:43 
GeneralMy vote of 1 Pin
Yang Yu1-Mar-10 3:42
Yang Yu1-Mar-10 3:42 
This article has not purpose. no background that applies to real world sitiuations. What is a POCO for WPF? and why do you need a generic mapper that is so decuppled? why not use Mapper<f,t> or even better, implement IConverter<f,t> which is actually supported by .NET framework.

There are some fundimental WRONG here. By inheritng from a GenericMapper abstract calss you are preventing the real class from having anything that is useful, the only higher order functions are the genericmappers... 2ndly, what if you want to convert to another type? or a 3rd type? you can't. Fundimentally what you want to achieve should be done using interfaces. So you could have Class: IMapper<t1>, IMapper<t2>... but this really is already done for you with .NET IConvertable.

Also, there is not value in simply mapping objects, what is the point? there should be losely decuppled transformations rules, by adding this feature maybe it will become more useful.

Please do not get offended at this comment. it is not personal.
Yang Yu
Prognex Corp.
www.prognex.com

GeneralRe: My vote of 1 Pin
Massimiliano Peluso "WeDev Limited"1-Mar-10 8:43
Massimiliano Peluso "WeDev Limited"1-Mar-10 8:43 
GeneralRe: My vote of 1 Pin
Yang Yu1-Mar-10 9:22
Yang Yu1-Mar-10 9:22 
GeneralRe: My vote of 1 [modified] Pin
Massimiliano Peluso "WeDev Limited"3-Mar-10 23:01
Massimiliano Peluso "WeDev Limited"3-Mar-10 23:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.