using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Magicodes.IE.Core;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEA_Core.Helper
{
public static class ExportHelper
{
///
/// 创建一个动态类,该类包含指定的属性集合
///
/// 要添加到动态类中的属性集合
/// 生成的动态类型
///
/// 该方法会为每个属性生成对应的字段和访问器,并为带有SugarColumn特性的属性添加ExporterHeaderAttribute特性
/// 动态类会被标记为ExcelExporterAttribute特性
///
public static Type CreateDynamicClass(this PropertyInfo[] propertyInfos)
{
string className = "DynamicClass";
AssemblyName assemblyName = new AssemblyName("WIDESEA_Model.Models");
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);//定义具有指定名称和访问权限的动态程序集
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");//在此程序集中定义命名的暂时动态模块
TypeBuilder typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public);//TypeBuilder:在运行时定义并创建类的新实例
Type attributeType1 = typeof(ExcelExporterAttribute);
MethodInfo [] methodInfos = attributeType1.GetMethods(BindingFlags.Public);
ConstructorInfo[] constructorInfos2 = attributeType1.GetConstructors();
ConstructorInfo constructorInfo2 = constructorInfos2[0];
CustomAttributeBuilder customAttributeBuilder2 = new CustomAttributeBuilder(constructorInfo2, new object[] { });
typeBuilder.SetCustomAttribute(customAttributeBuilder2);
foreach (var property in propertyInfos)
{
string propertyName = property.Name;
Type propertyType = property.PropertyType;
FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
SugarColumn sugarColumn = property.GetCustomAttribute();
if (sugarColumn != null)
{
Type attributeType = typeof(ExporterHeaderAttribute);
ConstructorInfo[] constructorInfos = attributeType.GetConstructors();
ConstructorInfo constructorInfo = constructorInfos[0];
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(constructorInfo, new object[] { sugarColumn.ColumnDescription, 11f, null, false, true, true, 0, KnownColor.Empty });
propertyBuilder.SetCustomAttribute(customAttributeBuilder);
}
MethodAttributes getSetAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_" + propertyName, getSetAttributes, propertyType, Type.EmptyTypes);
ILGenerator getIL = getMethodBuilder.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
getIL.Emit(OpCodes.Ret);
MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_" + propertyName, getSetAttributes, null, new Type[] { propertyType });
ILGenerator setIL = setMethodBuilder.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, fieldBuilder);
setIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getMethodBuilder);
propertyBuilder.SetSetMethod(setMethodBuilder);
}
Type generatedType = typeBuilder.CreateType();
return generatedType;
}
///
/// 设置对象的属性值
///
/// 目标对象实例
/// 要设置的属性名称
/// 要设置的属性值
public static void SetProperty(object instance, string propertyName, object value)
{
Type type = instance.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName);
propertyInfo.SetValue(instance, value);
}
///
/// 获取对象实例的指定属性值
///
/// 要获取属性的对象实例
/// 要获取的属性名称
/// 返回指定属性的值
public static object GetProperty(object instance, string propertyName)
{
Type type = instance.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName);
return propertyInfo.GetValue(instance);
}
///
/// 设置对象实例的属性值,通过反射将源对象T的属性值复制到目标实例中
///
/// 源对象类型
/// 目标对象实例
/// 包含属性值的源对象
///
/// 该方法会遍历源对象T的所有属性,通过反射获取并设置到目标实例对应的属性上,
/// 同时会检查属性是否标记了ExporterHeaderAttribute特性
///
public static void SetValue(object instance, T value)
{
Type type = instance.GetType();
PropertyInfo[] propertyInfos = typeof(T).GetProperties();
for (int j = 0; j < propertyInfos.Length; j++)
{
PropertyInfo propertyInfo = type.GetProperty(propertyInfos[j].Name);
object obj = propertyInfos[j].GetValue(value);
propertyInfo.SetValue(instance, obj);
ExporterHeaderAttribute exporterHeaderAttribute = propertyInfo.GetCustomAttribute();
}
}
}
}