Generic model mapper with .Net Reflection

Peter Sameh
Nov 5 · 3 min read

A real step by step example on how to implement Mapper with .Net Reflection


Have you ever been stuck before in transforming your models to your view models?
Many of us have the “REFLECTOPHOBIA” the fear of .Net reflections
So I am going to give a simple example in implementing a generic mapper using .Net reflection
to convert or transform any model, to any other model.
I will assume before starting this article that you have some .Net knowledge, C# and good OOP concepts.
Okay, if you have no .Net Reflection background at all, let me make it easier to you, Reflection gives you access to the .Net “Under the hood” or the lowest layer of C#.
You get your hands dirty using Reflection. For example you use the property types and names instead of their values.
So, let’s continue with our example. We are going to implement a Generic Mapper that can be used to map any model to any other model.
Let’s create a static class called GenericMapper
we will use LinQ, Reflection and Generics so, use these:

using System.Collections.Generic;
using System.Linq;
using System.Reflection;

Inside it, a static generic method called MapToModel like the following:
(use keyword this with the first argument, if you want to implement it as extension method)

public static K MapToModel<T,K>(T model, K mappedModel)

the first argument here, is the model to be mapped (the old model)
And the second argument, is the model that will be mapped and returned
Let’s think about the implementation
we want to check first if both models have mutual (common properties) to be mapped
so create two dictionaries each will be used to store each model’s properties

Dictionary<string,string> mappedProperties = new Dictionary<string,string>();
Dictionary<string,string> modelProperties = new Dictionary<string, string>();

Now the first use for Reflection we are going to fill these dictionaries with foreach
model (first argument): the given model
mappedModel (second argument): The new model we want to set

foreach (var property in mappedModel.GetType().GetProperties())
{
mappedProperties.Add(property.PropertyType.Name, property.Name);
}
foreach (var property in model.GetType().GetProperties())
{
modelProperties.Add(property.PropertyType.Name, property.Name);
}

GetType() method used to tell which type is this class (Student student) the type here is student.
.GetProperties to retrieve all the properties inside that class (StudentName, Age, Grades, Subjects,… )
Inside the foreach we can access now, the name of the property and its type,
property.PropertyType.Name to retrieve the type of the property as a string (StudentName is string)
and the property.Name is (StudentName) in this case.
After these 2 foreach(es) we have filled the dictionaries with every property type and name.
Now let’s compare if they have anything in common to be mapped by using LinQ intersection method

if (modelProperties.Intersect(mappedProperties).ToList().Count == 0)

Here we can throw an exception if it passes this condition, which means they don’t share anything in common

and if they have, will move to the next step.

Another use of Reflection

foreach to bring each property in the model we want to be mapped which is called (mappedModel) and set it with the adjacent value from the other class

(typical property names and types are very important here)

foreach (var property in mappedModel.GetType().GetProperties())
{
mappedModel.GetType().GetProperty(property.Name)

.SetValue(mappedModel, model.GetType().GetProperty(property.Name).GetValue(model));

}
return mappedModel;

Now foreach property again as we have seen before using the same methods (GetType() and GetProperties())

then in each loop, we bring this exact property using GetProperty by its name, and SetValue method, which takes two arguments in this case. The first argument is the object we want to set, and the second argument is the value itself. So again, we use GetProperty by its name from the other model to access THE SAME PROPERTY BY ITS NAME then we get its Value.

If you have any comment/ fix/ optimization kindly comment it.

Kindly note, this article is for practising purpose, and there are already some ready made libraries that do the same released and tested like the “AutoMapper” that you can use.

Thanks for reading.

Peter Sameh

Written by

A passionate software engineer, loves challenges, teaching and learning.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade