z8018
2 天以前 d8dc91f9c1fece5711e38edd1b1274cb9e579015
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
    {
        /// <summary>
        /// 创建一个动态类,该类包含指定的属性集合
        /// </summary>
        /// <param name="propertyInfos">要添加到动态类中的属性集合</param>
        /// <returns>生成的动态类型</returns>
        /// <remarks>
        /// 该方法会为每个属性生成对应的字段和访问器,并为带有SugarColumn特性的属性添加ExporterHeaderAttribute特性
        /// 动态类会被标记为ExcelExporterAttribute特性
        /// </remarks>
        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<SugarColumn>();
                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;
        }
 
        /// <summary>
        /// 设置对象的属性值
        /// </summary>
        /// <param name="instance">目标对象实例</param>
        /// <param name="propertyName">要设置的属性名称</param>
        /// <param name="value">要设置的属性值</param>
        public static void SetProperty(object instance, string propertyName, object value)
        {
            Type type = instance.GetType();
            PropertyInfo propertyInfo = type.GetProperty(propertyName);
            propertyInfo.SetValue(instance, value);
        }
 
        /// <summary>
        /// 获取对象实例的指定属性值
        /// </summary>
        /// <param name="instance">要获取属性的对象实例</param>
        /// <param name="propertyName">要获取的属性名称</param>
        /// <returns>返回指定属性的值</returns>
        public static object GetProperty(object instance, string propertyName)
        {
            Type type = instance.GetType();
            PropertyInfo propertyInfo = type.GetProperty(propertyName);
            return propertyInfo.GetValue(instance);
        }
 
        /// <summary>
        /// 设置对象实例的属性值,通过反射将源对象T的属性值复制到目标实例中
        /// </summary>
        /// <typeparam name="T">源对象类型</typeparam>
        /// <param name="instance">目标对象实例</param>
        /// <param name="value">包含属性值的源对象</param>
        /// <remarks>
        /// 该方法会遍历源对象T的所有属性,通过反射获取并设置到目标实例对应的属性上,
        /// 同时会检查属性是否标记了ExporterHeaderAttribute特性
        /// </remarks>
        public static void SetValue<T>(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<ExporterHeaderAttribute>();
            }
 
        }
 
    }
}