Using Reflection
you can read the fields
& properties
of an object
instance and can copy it over to another.
Like for a Mapper<From,To>
you need to provide the object
instance with values as From
then use (To)Activator.CreateInstance(typeof(To))
to create a new instance of To
and can copy over the fields
& properties
from <From>
to <To>
.
Mapper Class
The following is code is just trying to do the same. It comes with a Constructor
and 3 methods
which empowers it to Auto or Manually Map the fields between two classes.
public class Mapper<From,To>
{
private Dictionary<string,string> maptable;
private To returnObject;
private Type typeFrom;
private Type typeTo;
public Mapper()
{
maptable = new Dictionary<string,string>();
returnObject = (To)Activator.CreateInstance(typeof(To));
typeFrom = typeof(From);
typeTo = typeof(To);
}
public Mapper<From,To> Map(string from,string to)
{
maptable.Add(from,to);
return this;
}
public To ConvertTo(From from)
{
foreach (var from_field in typeFrom.GetFields())
{
if(maptable.Keys.Contains(from_field.Name))
{
var toFieldName = maptable[from_field.Name];
var fieldOfB = typeTo.GetField(toFieldName);
fieldOfB.SetValue(returnObject, from_field.GetValue(from));
}
}
foreach (var from_property in typeFrom.GetProperties())
{
if(maptable.Keys.Contains(from_property.Name))
{
var toPropertyName = maptable[from_property.Name];
var propertyOfB = typeTo.GetProperty(toPropertyName);
propertyOfB.SetValue(returnObject, from_property.GetValue(from));
}
}
return (To)returnObject;
}
public To AutoConvertTo<F, T>(From from)
{
foreach (var fieldOfA in typeFrom.GetFields())
{
var fieldOfB = typeTo.GetField(fieldOfA.Name);
fieldOfB.SetValue(returnObject, fieldOfA.GetValue(from));
}
foreach (var fromProperty in typeFrom.GetProperties())
{
var propertyOfB = typeTo.GetProperty(fromProperty.Name);
propertyOfB.SetValue(returnObject, fromProperty.GetValue(from));
}
return (To)returnObject;
}
}
Example Class A & B
To explain the code we need two example class:
public class A
{
public string Name { get; set; }
public int Count;
public string first {get;set;}
public string last {get;set;}
public int Age;
}
public class B
{
public string Name { get; set; }
public int Count;
public string first {get;set;}
public string last {get;set;}
public int Age;
public string ExclusiveB {get;set;}
}
Example
So if we create an instance of A
we can convert it to B
as in the example below.
// Instance of class A with data
var a = new A
{
Name = "a",
Count = 1,
first = "first",
last="last",
Age= 100
};
a.Dump("a"); //Dump is the function to display the output in Linqpad much like `Console.Write`
//Here we create an instance of the Mapper class
var m = new Mapper<A,B>();
// Then we are manually mapping the fields from A to B using dictionary
// Please note the datatype must match
m.Map("first","last");
m.Map("last","first");
m.Map("Age","Count");
m.Map("Count","Age");
m.Map("Name","Name");
//here we execute the manual mapping to convert `a` to `b2`
var manualB2 = m.ConvertTo(a);
manualB2.Dump("ManualMap"); //Display in console
//This is auto mapping the fields
var autoB = m.AutoConvertTo<A, B>(a);
autoB.Dump("AutoMap");
So we have AutoMapping where the fields/properties are cloned & copied as per their matching name and there is ManualMap which is created using the Map<From,To>()
method so you can map the fields/properties as you like.
Output
If everything works well you can see the out as
