using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace FreeSql.Extensions.DynamicEntity
{
///
/// 动态创建对象帮助类
///
public class DynamicCompileHelper
{
///
/// 动态构建Class - Type
///
///
public static DynamicCompileBuilder DynamicBuilder()
{
return new DynamicCompileBuilder();
}
///
/// 委托缓存
///
private static readonly ConcurrentDictionary
DelegateCache = new ConcurrentDictionary();
///
/// 设置动态对象的属性值
///
///
///
///
public static object CreateObjectByType(Type type, Dictionary porpertys)
{
if (type == null)
return null;
object istance = Activator.CreateInstance(type);
if (istance == null)
return null;
//根据key确定缓存
var cacheKey = $"{type.GetHashCode()}{porpertys.GetHashCode()}";
var dynamicDelegate = DelegateCache.GetOrAdd(cacheKey, key =>
{
//表达式目录树构建委托
var typeParam = Expression.Parameter(type);
var dicParamType = typeof(Dictionary);
var dicParam = Expression.Parameter(dicParamType);
var exps = new List();
var tempRef = Expression.Variable(typeof(object));
foreach (var pinfo in porpertys)
{
var propertyInfo = type.GetProperty(pinfo.Key);
if (propertyInfo == null)
continue;
var propertyName = Expression.Constant(pinfo.Key, typeof(string));
exps.Add(Expression.Call(dicParam, dicParamType.GetMethod("TryGetValue"), propertyName, tempRef));
exps.Add(Expression.Assign(Expression.MakeMemberAccess(typeParam, propertyInfo),
Expression.Convert(tempRef, propertyInfo.PropertyType)));
exps.Add(Expression.Assign(tempRef, Expression.Default(typeof(object))));
}
var returnTarget = Expression.Label(type);
exps.Add(Expression.Return(returnTarget, typeParam));
exps.Add(Expression.Label(returnTarget, Expression.Default(type)));
var block = Expression.Block(new[] { tempRef }, exps);
var @delegate = Expression.Lambda(block, typeParam, dicParam).Compile();
return @delegate;
});
var dynamicInvoke = dynamicDelegate.DynamicInvoke(istance, porpertys);
return dynamicInvoke;
}
}
}