77 lines
1.8 KiB
C#
77 lines
1.8 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
|
|
namespace MAX.Framework.Helpers;
|
|
|
|
public static class ObjectHelper
|
|
{
|
|
private static readonly ConcurrentDictionary<string, PropertyInfo> CachedObjectProperties =
|
|
new();
|
|
|
|
public static void TrySetProperty<TObject, TValue>(
|
|
TObject obj,
|
|
Expression<Func<TObject, TValue>> propertySelector,
|
|
Func<TValue> valueFactory,
|
|
params Type[] ignoreAttributeTypes
|
|
)
|
|
{
|
|
TrySetProperty(obj, propertySelector, x => valueFactory(), ignoreAttributeTypes);
|
|
}
|
|
|
|
public static void TrySetProperty<TObject, TValue>(
|
|
TObject obj,
|
|
Expression<Func<TObject, TValue>> propertySelector,
|
|
Func<TObject, TValue> valueFactory,
|
|
params Type[] ignoreAttributeTypes
|
|
)
|
|
{
|
|
string cacheKey =
|
|
$"{obj?.GetType().FullName}-"
|
|
+ $"{propertySelector}-"
|
|
+ $"{(ignoreAttributeTypes != null ? "-" + string.Join("-", ignoreAttributeTypes.Select(x => x.FullName)) : "")}";
|
|
|
|
PropertyInfo property = CachedObjectProperties.GetOrAdd(
|
|
cacheKey,
|
|
(name) =>
|
|
{
|
|
if (propertySelector.Body.NodeType != ExpressionType.MemberAccess)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
MemberExpression memberExpression = (MemberExpression)propertySelector.Body;
|
|
|
|
PropertyInfo? propertyInfo = obj?.GetType()
|
|
.GetProperties()
|
|
.FirstOrDefault(
|
|
x =>
|
|
x.Name == memberExpression.Member.Name
|
|
&& x.GetSetMethod(true) != null
|
|
);
|
|
|
|
if (propertyInfo == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (
|
|
ignoreAttributeTypes != null
|
|
&& ignoreAttributeTypes.Any(
|
|
ignoreAttribute => propertyInfo.IsDefined(ignoreAttribute, true)
|
|
)
|
|
)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return propertyInfo;
|
|
}
|
|
);
|
|
|
|
property?.SetValue(obj, valueFactory(obj));
|
|
}
|
|
}
|