using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; namespace xCommons.Extensions { public static partial class ModelExtensions { /// /// Update an Instance of a Typed Object with Data Provided by another Instance of Typed Object /// /// /// /// /// /// /// /// /// /// /// public static T UpdateData ( this T source, D updateWith, ICollection propertyWhiteList = null, ICollection propertyBlackList = null, ICollection>> propertyValueProviders = null, bool updateWithNullOrEmptyValues = false, bool throwExceptionOnFails = false ) where T : class where D : class { // var hasWhiteList = propertyWhiteList.HasChild (); var hasBlackList = propertyBlackList.HasChild (); var hasValueProvider = propertyValueProviders.HasChild>> (); // var fullPropertyList = updateWith.GetType ().GetProperties ().Select (prop => prop.Name); var mustSetProps = (hasWhiteList ? propertyWhiteList : fullPropertyList); // if (hasBlackList) { mustSetProps = mustSetProps.Where (propName => !propertyBlackList.Contains (propName)); } // mustSetProps.ToList ().ForEach (propName => { // try { // var sourceProp = source.GetType ().GetProperty (propName); var sourceValue = sourceProp.GetValue (source); var sourceValueType = sourceValue.IsNull () ? null : sourceValue.GetType (); // var updateWithProp = updateWith.GetType ().GetProperty (propName); var updateWithValue = updateWithProp.GetValue (updateWith); var updateWithValueType = updateWithValue.IsNull () ? null : updateWithValue.GetType (); // var valueProviderValue = hasValueProvider ? propertyValueProviders .FirstOrDefault (p => p.Key == propName).Value : null; var updateVal = !valueProviderValue.IsNull () ? valueProviderValue.Invoke (updateWith) : (updateWithValue.IsNull () && !updateWithNullOrEmptyValues) ? sourceValue : updateWithValue; var updateValType = updateVal.IsNull () ? null : updateVal.GetType (); // Type t = Nullable.GetUnderlyingType (sourceProp.PropertyType) ?? sourceProp.PropertyType; object safeValue = (updateVal == null) ? null : !updateValType.IsCollectionType () ? Convert.ChangeType (updateVal, t) : updateVal; // sourceProp.SetValue (source, safeValue); } catch (Exception ex) { // if (throwExceptionOnFails) { throw ex; } } }); // return source; } /// /// Check two Instance of Typed Object Values are Same or not /// /// /// /// /// /// /// /// /// /// /// public static bool IsSameContent ( this T source, D dest, ICollection propertyWhiteList = null, ICollection propertyBlackList = null, ICollection>> propertyValueCheckers = null, bool throwExceptionOnFails = false ) where T : class where D : class { // var hasWhiteList = propertyWhiteList.HasChild (); var hasBlackList = propertyBlackList.HasChild (); var hasCheckerProvider = propertyValueCheckers.HasChild>> (); // var fullPropertyList = dest.GetType ().GetProperties ().Select (prop => prop.Name); var mustCheckProps = (hasWhiteList ? propertyWhiteList : fullPropertyList); if (hasBlackList) { mustCheckProps = mustCheckProps.Where (propName => !propertyBlackList.Contains (propName)); } // var result = true; mustCheckProps.ToList ().ForEach (propName => { // try { // var sourceProp = source.GetType ().GetProperty (propName); var destProp = dest.GetType ().GetProperty (propName); // // Check Types ... var isSameType = true; // // Check var isSameValue = false; var mustDoCustomCheck = hasCheckerProvider && propertyValueCheckers.Any (p => p.Key == propName); if (mustDoCustomCheck) { // // Check Values ... var valueChecker = propertyValueCheckers.FirstOrDefault (p => p.Key == propName).Value; isSameValue = valueChecker.Invoke (source, dest); } else { // // // isSameType = (sourceProp.PropertyType == destProp.PropertyType && // sourceProp.ReflectedType == destProp.ReflectedType); // // Check Values ... isSameValue = Equals (sourceProp.GetValue (source), destProp.GetValue (dest)); } // if (!isSameType || !isSameValue) { result = false; } } catch (Exception ex) { // if (throwExceptionOnFails) { throw ex; } } }); // return result; } /// /// Check specific type is Collection Type or not /// /// /// public static bool IsCollectionType (this Type source) { // if (source.IsNull () || !source.IsGenericType) { return false; } // var genericTypeDefinition = source.GetGenericTypeDefinition (); var result = genericTypeDefinition == typeof (List<>) || genericTypeDefinition == typeof (HashSet<>) || genericTypeDefinition == typeof (Collection<>) || genericTypeDefinition == typeof (ICollection<>) || genericTypeDefinition == typeof (IEnumerable<>); // return result; } /// /// Retrieve a Property Value in Generic /// /// /// /// public static string GetPropValues (this T item) where T : class { // var props = item.GetType ().GetProperties (); var vals = props.Select (p => p.GetValue (item)); // return vals.ToJSON (); } /// /// Check a Property Value Contains specific value /// /// /// /// /// public static bool PropValuesContains (this T item, string value) where T : class { // return item.GetPropValues () .ToNormalString () .Contains (value .ToNormalString ()); } /// /// Generate Default Column Map /// /// /// /// public static IDictionary>> GetDefaultColumnsMap (this T item) where T : class { // if (item.IsNull ()) { return null; } // var result = new Dictionary>> (); var props = item.GetType ().GetProperties (); // foreach (var prop in props) { result.Add (prop.Name, t => t.GetType ().GetProperty (prop.Name).GetValue (t, null)); } // return result; } /// /// Generate Default Column Map /// /// /// /// public static IDictionary GetPropValuesDictionary (this T item) where T : class { // if (item.IsNull ()) { return null; } // var result = new Dictionary (); var props = item.GetType ().GetProperties (); // foreach (var prop in props) { result.Add (prop.Name, prop.GetValue (item).ToJSON ()); } // return result; } } }