General Purpose Data Synchronization Between Objects – The Easy Way
by Joel Holder
SomeObjectA</font></font> sourceObjRef = new SomeObjectA();
SomeObjectB targetObjRef = new SomeObjectB(); </p>
</font>new ReflectionSynchronizer().Sync(sourceObjRef , targetObjRef ); </font></div>
IDictionary sourceDictionary = new Hashtable(); SomeObject targetObjRef = new SomeObject(); </p>
</font>new ReflectionSynchronizer().Sync(sourceDictionary , targetObjRef ); here is the class: </font> </div>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Reflection; using System.Diagnostics; using System.Collections; namespace Helpers { public class ReflectionSynchronizer { /// </p>
/// synchronizes a Dictionary to an objects properties /// uses reflection to figure out types to convert objects in entry.Value to when setting object’s properties /// </summary>
</span></span> /// </param> /// </param> public void Sync(IDictionary source, object target) { foreach (DictionaryEntry entry in source) { try { PropertyInfo targetObjectProperty = target.GetType().GetProperty(entry.Key.ToString()); if (targetObjectProperty != null) { object sourceObjectValue = entry.Value; if (sourceObjectValue != null) { //does handle nullable types – see overload for known in advanced object valueToAssign = null; To(sourceObjectValue, out valueToAssign, sourceObjectValue.GetType()); if (valueToAssign != null) { targetObjectProperty.SetValue(target, valueToAssign, null); } } } } catch (ApplicationException ex) { Debug.WriteLine(ex.Message); } } } /// </p>
/// synchronizes an object reference’s properties’ values to another object reference’s properties’ values /// </summary>
</span></span> /// </param> /// </param> public void Sync(object source, object target) { foreach (PropertyInfo sourceObjectProperty in source.GetType().GetProperties()) { try { PropertyInfo targetObjectProperty = target.GetType().GetProperty(sourceObjectProperty.Name); if (targetObjectProperty != null && targetObjectProperty.PropertyType.Equals(sourceObjectProperty.PropertyType)) { object sourceObjectValue = sourceObjectProperty.GetValue(source, null); if (sourceObjectValue != null) { //does handle nullable types – see overload for known in advanced object valueToAssign = null; To(sourceObjectValue, out valueToAssign, sourceObjectValue.GetType()); if (valueToAssign != null) { targetObjectProperty.SetValue(target, valueToAssign, null); } } } } catch (ApplicationException ex) { Debug.WriteLine(ex.Message); } } } /// </p>
/// copies a value to another /// </summary>
</span></span> /// </param> /// </param> /// </param> public void To(object srcValue, out object targetValue, Type t) { targetValue = null; if (srcValue == DBNull.Value) return; if (IsNullable(t)) { if (srcValue == null) { return; } targetValue = UnderlyingTypeOf(t); } targetValue = Convert.ChangeType(srcValue, t); } /// </p>
/// generic version of To /// </summary>
</span></span> /// /// </param> /// </param> /// public T To { if (value == DBNull.Value) return defaultValue; Type t = typeof(T); if (IsNullable(t)) { if (value == null) return default(T); t = UnderlyingTypeOf(t); } return (T)Convert.ChangeType(value, t); } /// </p>
/// figures out if the Type is Nullable”/> /// </summary>
</span></span> /// </param> /// private bool IsNullable(Type t) { if (!t.IsGenericType) return false; Type g = t.GetGenericTypeDefinition(); return (g.Equals(typeof(Nullable<>))); } /// </p>
/// gets the underlying Type /// </summary>
</span></span> /// </param> /// private Type UnderlyingTypeOf(Type t) { return t.GetGenericArguments()[0]; } } }