Mega Code Archive

 
Categories / C# / Reflection
 

Provides a simple reflection based mapper to perform a Data Mapping between two types of objects

//--------------------------------------------------------------------- //  This file is part of the Background Motion solution. //  //  Copyright (C) Mindscape (TM).  All rights reserved. //  http://www.mindscape.co.nz //  //  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A //  PARTICULAR PURPOSE. //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Reflection; namespace Mindscape.BackgroundMotion.Core.Utilities {   /// <summary>   /// Provides a simple reflection based mapper to perform a Data Mapping between two types of objects   /// </summary>   /// <remarks>   /// We are working on the convention that the source object will be property based and the target will be field based   /// This is used between our domain entities and DTO's   /// </remarks>   /// <typeparam name="T"></typeparam>   public class DataMapper<T> where T : new()   {     // TODO: Not thread-safe - using ThreadStatic should be ok here     private static Dictionary<Type, Dictionary<string, PropertyInfo>> _propertyReflectionCache =       new Dictionary<Type, Dictionary<string, PropertyInfo>>();     private static Dictionary<Type, FieldInfo[]> _fieldReflectionCache = new Dictionary<Type, FieldInfo[]>();     /// <summary>     /// Use a reflection based mapping to map between properties and fields     /// </summary>     public static T Map(object source)     {       T target = new T();       FieldInfo[] fields = GetFieldSetInfo(typeof(T));       if (source == null)       {         return target;       }       foreach (FieldInfo field in fields)       {         try         {           PropertyInfo sourceProperty = GetPropertyInfo(source.GetType(), field.Name);           if (sourceProperty == null)           {             continue;           }           field.SetValue(target, sourceProperty.GetValue(source, null));         }         catch (InvalidCastException)         {         }       }       return target;     }     /// <summary>     /// Finds a property in the reflection cache     /// </summary>     private static PropertyInfo GetPropertyInfo(Type t, string name)     {       if (_propertyReflectionCache.ContainsKey(t))       {         if (_propertyReflectionCache[t].ContainsKey(name))         {           return _propertyReflectionCache[t][name];         }         _propertyReflectionCache[t].Add(name, t.GetProperty(name, BindingFlags.Public | BindingFlags.Instance));         return _propertyReflectionCache[t][name];       }       Dictionary<string, PropertyInfo> dictionary = new Dictionary<string, PropertyInfo>();       _propertyReflectionCache.Add(t, dictionary);       dictionary.Add(name, t.GetProperty(name, BindingFlags.Public | BindingFlags.Instance));       return _propertyReflectionCache[t][name];     }     /// <summary>     /// Finds a collection of field information from the reflection cache     /// </summary>     private static FieldInfo[] GetFieldSetInfo(Type t)     {       if (_fieldReflectionCache.ContainsKey(t))       {         return _fieldReflectionCache[t];       }       _fieldReflectionCache.Add(t, t.GetFields(BindingFlags.Public | BindingFlags.Instance));       return _fieldReflectionCache[t];     }   } }