Skip to content

Instantly share code, notes, and snippets.

@dervalp
Created February 17, 2012 13:45
Show Gist options
  • Select an option

  • Save dervalp/1853521 to your computer and use it in GitHub Desktop.

Select an option

Save dervalp/1853521 to your computer and use it in GitHub Desktop.
Mapper C#
[AttributeUsage(AttributeTargets.Property)]
public sealed class NotMappingAttribute : Attribute
{
public bool Value { get; private set; }
public NotMappingAttribute()
{
Value = true;
}
}
public class Mapper<TSource, TDestination>
{
/// <summary>
/// Dictionnary Used for supporting Aggregates
/// Dictionnary {
/// Model.Address : AddressViewModel
/// Model.WhatEvertComesFromDomain : WhateverViewModel
/// }
/// </summary>
Dictionary<string, string> MappingRelations { get; set; }
/// <summary>
/// Constructor, pass Aggregates relation for supporting them
/// </summary>
/// <param name="mappingInformationDomainToViewModel"></param>
public Mapper(Dictionary<string, string> mappingInformationDomainToViewModel = null)
{
MappingRelations = mappingInformationDomainToViewModel;
}
/// <summary>
/// Take instance of sourceType and map an instance of destinationType
/// If no MappingRelations defined during CTOR:
/// map ONLY PROPERTIES with the SAME NAME and SAME TYPE
/// If MappingRelations defined during CTOR:
/// Reccursivelly instanciate the MapClass<TSource, TDestination> and called the MapClassReflection with types passed
/// For example : MapClassReflection<AddressViewModel,AddressViewModel> is instanciate and the MapClassReflection method
/// is called
/// </summary>
/// <param name="source">Source Type</param>
/// <param name="destination">Destination Type</param>
public void MapClassReflection(TSource source, TDestination destination)
{
if (source != null)
{
try
{
foreach (PropertyInfo sourceProperty in source.GetType().GetProperties())
{
string destinationPropertyName = LookupForPropertyInDestinationType(sourceProperty.Name, destination.GetType());
if (destinationPropertyName != null)
{
PropertyInfo destinationProperty = destination.GetType().GetProperty(destinationPropertyName);
NotMappingAttribute DoNotMap = (NotMappingAttribute)Attribute.GetCustomAttribute(destinationProperty, typeof(NotMappingAttribute));
if (DoNotMap != null && DoNotMap.Value == true)
{
continue;
}
//if (!destinationProperty.CanWrite && sourceProperty.CanRead)
//{
// throw new MappingException<TSource, TDestination>(ExceptionMessage.MappingException() + "-" + "Set accessor is not accessible on '" + destinationProperty.Name + "'");
//}
if (destinationProperty.PropertyType == sourceProperty.PropertyType)
{
if (source != null)
{
destinationProperty.SetValue(destination, sourceProperty.GetValue(source, null), null);
}
}
else
{
if (MappingRelations != null)
{
if (HasAggregatesDefined(sourceProperty.PropertyType.ToString()))
{
Type d1 = typeof(Mapper<,>);
Type[] typeArgs = { sourceProperty.PropertyType, destinationProperty.PropertyType };
Type constructed = d1.MakeGenericType(typeArgs);
Object[] _parameterss = new Object[1];
_parameterss[0] = MappingRelations;
object o = Activator.CreateInstance(constructed, _parameterss);
MethodInfo theMethod = constructed.GetMethod("MapClassReflection");
object[] _parameters = new object[2];
_parameters[0] = sourceProperty.GetValue(source, null);
_parameters[1] = destinationProperty.GetValue(destination, null);
theMethod.Invoke(o, _parameters);
}
}
}
}
}
}
catch (System.Exception ex)
{
throw new MappingException<TSource, TDestination>(ExceptionMessage.MappingException() + "-" + ex.Message);
}
}
}
private bool HasAggregatesDefined(string sourceTypeName)
{
return (string.IsNullOrEmpty(MappingRelations.Where(x => x.Key == sourceTypeName).FirstOrDefault().Value)) ? false : true;
}
/// <summary>
/// Loop inside the DestinationType and return the PropertyName if there is a matching Proprety with the sourceType
/// For matching it have to be the same Name
/// </summary>
/// <param name="sourcePropertyName"></param>
/// <param name="destinationType"></param>
/// <returns></returns>
private static string LookupForPropertyInDestinationType(string sourcePropertyName, Type destinationType)
{
foreach (PropertyInfo property in destinationType.GetProperties())
{
if (property.Name == sourcePropertyName)
{
return sourcePropertyName;
}
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment