add some Reflection Extensions Method ...

This commit is contained in:
2026-04-27 21:42:47 +03:30
parent 0d16c9574e
commit 5293e18b1b
+221 -83
View File
@@ -4,8 +4,10 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
namespace xCommons.Extensions { namespace xCommons.Extensions
public static partial class ModelExtensions { {
public static partial class ModelExtensions
{
/// <summary> /// <summary>
/// Update an Instance of a Typed Object with Data Provided by another Instance of Typed Object /// Update an Instance of a Typed Object with Data Provided by another Instance of Typed Object
/// </summary> /// </summary>
@@ -19,7 +21,7 @@ namespace xCommons.Extensions {
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <typeparam name="D"></typeparam> /// <typeparam name="D"></typeparam>
/// <returns></returns> /// <returns></returns>
public static T UpdateData<T, D> ( public static T UpdateData<T, D>(
this T source, this T source,
D updateWith, D updateWith,
ICollection<string> propertyWhiteList = null, ICollection<string> propertyWhiteList = null,
@@ -29,58 +31,65 @@ namespace xCommons.Extensions {
bool throwExceptionOnFails = false bool throwExceptionOnFails = false
) )
where T : class where T : class
where D : class { where D : class
{
// //
var hasWhiteList = propertyWhiteList.HasChild<string> (); var hasWhiteList = propertyWhiteList.HasChild<string>();
var hasBlackList = propertyBlackList.HasChild<string> (); var hasBlackList = propertyBlackList.HasChild<string>();
var hasValueProvider = propertyValueProviders.HasChild<KeyValuePair<string, Func<D, object>>> (); var hasValueProvider = propertyValueProviders.HasChild<KeyValuePair<string, Func<D, object>>>();
// //
var fullPropertyList = updateWith.GetType ().GetProperties ().Select (prop => prop.Name); var fullPropertyList = updateWith.GetType().GetProperties().Select(prop => prop.Name);
var mustSetProps = (hasWhiteList ? propertyWhiteList : fullPropertyList); var mustSetProps = (hasWhiteList ? propertyWhiteList : fullPropertyList);
// //
if (hasBlackList) { if (hasBlackList)
mustSetProps = mustSetProps.Where (propName => !propertyBlackList.Contains (propName)); {
mustSetProps = mustSetProps.Where(propName => !propertyBlackList.Contains(propName));
} }
// //
mustSetProps.ToList ().ForEach (propName => { mustSetProps.ToList().ForEach(propName =>
{
// //
try { try
{
// //
var sourceProp = source.GetType ().GetProperty (propName); var sourceProp = source.GetType().GetProperty(propName);
var sourceValue = sourceProp.GetValue (source); var sourceValue = sourceProp.GetValue(source);
var sourceValueType = sourceValue.IsNull () ? null : sourceValue.GetType (); var sourceValueType = sourceValue.IsNull() ? null : sourceValue.GetType();
// //
var updateWithProp = updateWith.GetType ().GetProperty (propName); var updateWithProp = updateWith.GetType().GetProperty(propName);
var updateWithValue = updateWithProp.GetValue (updateWith); var updateWithValue = updateWithProp.GetValue(updateWith);
var updateWithValueType = updateWithValue.IsNull () ? null : updateWithValue.GetType (); var updateWithValueType = updateWithValue.IsNull() ? null : updateWithValue.GetType();
// //
var valueProviderValue = hasValueProvider ? propertyValueProviders var valueProviderValue = hasValueProvider ? propertyValueProviders
.FirstOrDefault (p => p.Key == propName).Value : null; .FirstOrDefault(p => p.Key == propName).Value : null;
var updateVal = !valueProviderValue.IsNull () ? var updateVal = !valueProviderValue.IsNull() ?
valueProviderValue.Invoke (updateWith) : valueProviderValue.Invoke(updateWith) :
(updateWithValue.IsNull () && !updateWithNullOrEmptyValues) ? (updateWithValue.IsNull() && !updateWithNullOrEmptyValues) ?
sourceValue : updateWithValue; sourceValue : updateWithValue;
var updateValType = updateVal.IsNull () ? null : updateVal.GetType (); var updateValType = updateVal.IsNull() ? null : updateVal.GetType();
// //
Type t = Nullable.GetUnderlyingType (sourceProp.PropertyType) ?? sourceProp.PropertyType; Type t = Nullable.GetUnderlyingType(sourceProp.PropertyType) ?? sourceProp.PropertyType;
object safeValue = object safeValue =
(updateVal == null) ? (updateVal == null) ?
null : null :
!updateValType.IsCollectionType () ? !updateValType.IsCollectionType() ?
Convert.ChangeType (updateVal, t) : Convert.ChangeType(updateVal, t) :
updateVal; updateVal;
// //
sourceProp.SetValue (source, safeValue); sourceProp.SetValue(source, safeValue);
} catch (Exception ex) { }
catch (Exception ex)
{
// //
if (throwExceptionOnFails) { if (throwExceptionOnFails)
{
throw ex; throw ex;
} }
} }
@@ -90,6 +99,114 @@ namespace xCommons.Extensions {
return source; return source;
} }
/// <summary>
/// Check a Class is Contains a Property or not ...
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="property"></param>
/// <returns></returns>
public static bool HasProperty<T>(
this T source,
string property
)
where T : class
{
//
var result = source
.GetType()
.GetProperties()
.Any(prop => prop.Name == property); ;
//
return result;
}
/// <summary>
/// Get a Class Property Value using Generic Concept ...
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp"></typeparam>
/// <param name="source"></param>
/// <param name="property"></param>
/// <returns></returns>
public static TProp GetProperty<T, TProp>(
this T source,
string property
)
where T : class
{
//
TProp result = default(TProp);
//
// Check if T Has Property ...
if (source.HasProperty(property))
{
//
// Access Property ...
var prop = source
.GetType()
.GetProperty(property);
//
// Retrieve Property Value as Object ...
var propVal = prop.GetValue(source);
//
result = (TProp)propVal;
}
//
return result;
}
/// <summary>
/// Setting Property Value of T ...
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp"></typeparam>
/// <param name="source"></param>
/// <param name="property"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool SetProperty<T, TProp>(
this T source,
string property,
TProp value
)
where T : class
{
//
// Check T Has Property ...
var result = source.HasProperty(property);
if (!result)
{
return result;
}
//
// Access Property ...
var prop = source
.GetType()
.GetProperty(property);
//
// Set Property ...
try
{
//
result = true;
prop.SetValue(source, value);
}
catch
{
result = false;
}
//
return result;
}
/// <summary> /// <summary>
/// Check two Instance of Typed Object Values are Same or not /// Check two Instance of Typed Object Values are Same or not
@@ -103,7 +220,7 @@ namespace xCommons.Extensions {
/// /// <typeparam name="T"></typeparam> /// /// <typeparam name="T"></typeparam>
/// <typeparam name="D"></typeparam> /// <typeparam name="D"></typeparam>
/// <returns></returns> /// <returns></returns>
public static bool IsSameContent<T, D> ( public static bool IsSameContent<T, D>(
this T source, this T source,
D dest, D dest,
ICollection<string> propertyWhiteList = null, ICollection<string> propertyWhiteList = null,
@@ -112,27 +229,31 @@ namespace xCommons.Extensions {
bool throwExceptionOnFails = false bool throwExceptionOnFails = false
) )
where T : class where T : class
where D : class { where D : class
{
// //
var hasWhiteList = propertyWhiteList.HasChild<string> (); var hasWhiteList = propertyWhiteList.HasChild<string>();
var hasBlackList = propertyBlackList.HasChild<string> (); var hasBlackList = propertyBlackList.HasChild<string>();
var hasCheckerProvider = propertyValueCheckers.HasChild<KeyValuePair<string, Func<T, D, bool>>> (); var hasCheckerProvider = propertyValueCheckers.HasChild<KeyValuePair<string, Func<T, D, bool>>>();
// //
var fullPropertyList = dest.GetType ().GetProperties ().Select (prop => prop.Name); var fullPropertyList = dest.GetType().GetProperties().Select(prop => prop.Name);
var mustCheckProps = (hasWhiteList ? propertyWhiteList : fullPropertyList); var mustCheckProps = (hasWhiteList ? propertyWhiteList : fullPropertyList);
if (hasBlackList) { if (hasBlackList)
mustCheckProps = mustCheckProps.Where (propName => !propertyBlackList.Contains (propName)); {
mustCheckProps = mustCheckProps.Where(propName => !propertyBlackList.Contains(propName));
} }
// //
var result = true; var result = true;
mustCheckProps.ToList ().ForEach (propName => { mustCheckProps.ToList().ForEach(propName =>
{
// //
try { try
{
// //
var sourceProp = source.GetType ().GetProperty (propName); var sourceProp = source.GetType().GetProperty(propName);
var destProp = dest.GetType ().GetProperty (propName); var destProp = dest.GetType().GetProperty(propName);
// //
// Check Types ... // Check Types ...
@@ -141,29 +262,36 @@ namespace xCommons.Extensions {
// //
// Check // Check
var isSameValue = false; var isSameValue = false;
var mustDoCustomCheck = hasCheckerProvider && propertyValueCheckers.Any (p => p.Key == propName); var mustDoCustomCheck = hasCheckerProvider && propertyValueCheckers.Any(p => p.Key == propName);
if (mustDoCustomCheck) { if (mustDoCustomCheck)
{
// //
// Check Values ... // Check Values ...
var valueChecker = propertyValueCheckers.FirstOrDefault (p => p.Key == propName).Value; var valueChecker = propertyValueCheckers.FirstOrDefault(p => p.Key == propName).Value;
isSameValue = valueChecker.Invoke (source, dest); isSameValue = valueChecker.Invoke(source, dest);
} else { }
else
{
// // // //
// isSameType = (sourceProp.PropertyType == destProp.PropertyType && // isSameType = (sourceProp.PropertyType == destProp.PropertyType &&
// sourceProp.ReflectedType == destProp.ReflectedType); // sourceProp.ReflectedType == destProp.ReflectedType);
// //
// Check Values ... // Check Values ...
isSameValue = Equals (sourceProp.GetValue (source), destProp.GetValue (dest)); isSameValue = Equals(sourceProp.GetValue(source), destProp.GetValue(dest));
} }
// //
if (!isSameType || !isSameValue) { if (!isSameType || !isSameValue)
{
result = false; result = false;
} }
} catch (Exception ex) { }
catch (Exception ex)
{
// //
if (throwExceptionOnFails) { if (throwExceptionOnFails)
{
throw ex; throw ex;
} }
} }
@@ -178,19 +306,21 @@ namespace xCommons.Extensions {
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <returns></returns> /// <returns></returns>
public static bool IsCollectionType (this Type source) { public static bool IsCollectionType(this Type source)
{
// //
if (source.IsNull () || !source.IsGenericType) { if (source.IsNull() || !source.IsGenericType)
{
return false; return false;
} }
// //
var genericTypeDefinition = source.GetGenericTypeDefinition (); var genericTypeDefinition = source.GetGenericTypeDefinition();
var result = genericTypeDefinition == typeof (List<>) || var result = genericTypeDefinition == typeof(List<>) ||
genericTypeDefinition == typeof (HashSet<>) || genericTypeDefinition == typeof(HashSet<>) ||
genericTypeDefinition == typeof (Collection<>) || genericTypeDefinition == typeof(Collection<>) ||
genericTypeDefinition == typeof (ICollection<>) || genericTypeDefinition == typeof(ICollection<>) ||
genericTypeDefinition == typeof (IEnumerable<>); genericTypeDefinition == typeof(IEnumerable<>);
// //
return result; return result;
@@ -202,14 +332,15 @@ namespace xCommons.Extensions {
/// <param name="item"></param> /// <param name="item"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static string GetPropValues<T> (this T item) public static string GetPropValues<T>(this T item)
where T : class { where T : class
{
// //
var props = item.GetType ().GetProperties (); var props = item.GetType().GetProperties();
var vals = props.Select (p => p.GetValue (item)); var vals = props.Select(p => p.GetValue(item));
// //
return vals.ToJSON (); return vals.ToJSON();
} }
/// <summary> /// <summary>
@@ -219,13 +350,14 @@ namespace xCommons.Extensions {
/// <param name="value"></param> /// <param name="value"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static bool PropValuesContains<T> (this T item, string value) public static bool PropValuesContains<T>(this T item, string value)
where T : class { where T : class
{
// //
return item.GetPropValues () return item.GetPropValues()
.ToNormalString () .ToNormalString()
.Contains (value .Contains(value
.ToNormalString ()); .ToNormalString());
} }
/// <summary> /// <summary>
@@ -234,20 +366,23 @@ namespace xCommons.Extensions {
/// <param name="item"></param> /// <param name="item"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static IDictionary<string, Expression<Func<T, object>>> GetDefaultColumnsMap<T> (this T item) public static IDictionary<string, Expression<Func<T, object>>> GetDefaultColumnsMap<T>(this T item)
where T : class { where T : class
{
// //
if (item.IsNull ()) { if (item.IsNull())
{
return null; return null;
} }
// //
var result = new Dictionary<string, Expression<Func<T, object>>> (); var result = new Dictionary<string, Expression<Func<T, object>>>();
var props = item.GetType ().GetProperties (); var props = item.GetType().GetProperties();
// //
foreach (var prop in props) { foreach (var prop in props)
result.Add (prop.Name, t => t.GetType ().GetProperty (prop.Name).GetValue (t, null)); {
result.Add(prop.Name, t => t.GetType().GetProperty(prop.Name).GetValue(t, null));
} }
// //
@@ -260,20 +395,23 @@ namespace xCommons.Extensions {
/// <param name="item"></param> /// <param name="item"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static IDictionary<string, string> GetPropValuesDictionary<T> (this T item) public static IDictionary<string, string> GetPropValuesDictionary<T>(this T item)
where T : class { where T : class
{
// //
if (item.IsNull ()) { if (item.IsNull())
{
return null; return null;
} }
// //
var result = new Dictionary<string, string> (); var result = new Dictionary<string, string>();
var props = item.GetType ().GetProperties (); var props = item.GetType().GetProperties();
// //
foreach (var prop in props) { foreach (var prop in props)
result.Add (prop.Name, prop.GetValue (item).ToJSON ()); {
result.Add(prop.Name, prop.GetValue(item).ToJSON());
} }
// //