/// <summary> /// Merge two different object instances into a single object which is a super-set of the properties of both objects. /// If property name collision occurs and no policy has been created to specify which to use using the .Use() method the property value from 'values1' will be used. /// </summary> /// <param name="values1">An object to be merged.</param> /// <param name="values2">An object to be merged.</param> /// <returns>New object containing properties from both objects</returns> public static object Merge(object values1, object values2) { //lock for thread safe writing lock (_syncLock) { //create a name from the names of both Types var name = string.Format("{0}_{1}", values1.GetType(), values2.GetType()); if (typeMergerPolicy != null) { name += "_" + string.Join(",", typeMergerPolicy.IgnoredProperties.Select(x => string.Format("{0}_{1}", x.Item1, x.Item2))); } //now that we're inside the lock - check one more time var result = CreateInstance(name, values1, values2); if (result != null) { typeMergerPolicy = null; return(result); } //merge list of PropertyDescriptors for both objects var pdc = GetProperties(values1, values2); //make sure static properties are properly initialized InitializeAssembly(); //create the type definition var newType = CreateType(name, pdc); //add it to the cache anonymousTypes.Add(name, newType); //return an instance of the new Type result = CreateInstance(name, values1, values2); typeMergerPolicy = null; return(result); } }
/// <summary> /// Used internally by the TypeMergerPolicy class method chaining for specifying a policy to use during merging. /// </summary> internal static object Merge(object values1, object values2, xTypeMergerPolicy policy) { typeMergerPolicy = policy; return(Merge(values1, values2)); }