动态生成类并通过反射调用

动态生成类并通过反射调用

using CZGL.Roslyn;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis;
using System.Reflection;
using Magicodes.ExporterAndImporter.Excel;
using Magicodes.ExporterAndImporter.Core;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Text.Json;

namespace ConsoleApp3
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var classCode = $@"
                    
                               
                            using Magicodes.ExporterAndImporter.Core;
                            using Magicodes.ExporterAndImporter.Excel;
                            using System.ComponentModel.DataAnnotations;

namespace ConsoleApp3
{{
                            /// <summary>
                            /// 导入学生数据Dto
                            /// IsLabelingError:是否标注数据错误
                            /// </summary>
                            [ExcelImporter(IsLabelingError = true)]
                            public class ImportStudentDto
                            {{
                                /// <summary>
                                ///     序号
                                /// </summary>
                                [ImporterHeader(Name = ""序号"")]
                                public long Id {{ get; set; }}


                                /// <summary>
                                ///     姓名
                                /// </summary>
                                [ImporterHeader(Name = ""姓名"")]
                                [Required(ErrorMessage = ""学生姓名不能为空"")]
                                [MaxLength(50, ErrorMessage = ""名称字数超出最大限制, 请修改!"")]
                                public string Name {{ get; set; }}

                            }}

}}

            ".Trim();

            // 编译选项
            // 编译选项可以不配置
            DomainOptionBuilder option = new DomainOptionBuilder()
                .WithPlatform(Platform.AnyCpu)                     // 生成可移植程序集
                .WithDebug(false)                                  // 使用 Release 编译
                .WithKind(OutputKind.DynamicallyLinkedLibrary)     // 生成动态库
                .WithLanguageVersion(LanguageVersion.CSharp7_3);   // 使用 C# 7.3


            CompilationBuilder builder = CodeSyntax.CreateCompilation("Test.dll")
                .WithPath(Directory.GetParent(typeof(Program).Assembly.Location).FullName)
                .WithOption(option)                                // 可以省略
                .WithAutoAssembly()                                // 自动添加程序集引用
                .WithAssembly(typeof(ExcelImporterAttribute))
                .WithAssembly(typeof(ImporterHeaderAttribute))
                .WithAssembly(typeof(RequiredAttribute))
                .WithNamespace(NamespaceBuilder.FromCode(classCode));

            try
            {
                if (builder.CreateDomain(out var messages))
                {
                    Console.WriteLine("编译成功!开始执行程序集进行验证!");
                    var assembly = Assembly.LoadFile(Directory.GetParent(typeof(Program).Assembly.Location).FullName + "/Test.dll");
                    var type = assembly.GetType("ConsoleApp3.ImportStudentDto");
                    var method = type.GetMethod("MyMethod");

                    object obj = Activator.CreateInstance(type);

                    Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(obj));


                    Import(obj).Wait();

                    string result = (string)method.Invoke(obj, null);

                    if (result.Equals("测试成功"))
                        Console.WriteLine("执行程序集测试成功!");
                    else
                        Console.WriteLine("执行程序集测试失败!");
                }
                else
                {
                    _ = messages.Execute(item =>
                    {
                        Console.WriteLine(@$"ID:{item.Id}
严重程度:{item.Severity}     
位置:{item.Location.SourceSpan.Start}~{item.Location.SourceSpan.End}
消息:{item.Descriptor.Title}   {item}");
                    });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex.ToString()}");
            }

        }

        public static async Task Import(object obj)
        {
            IExcelImporter Importer = new ExcelImporterExt();
            MethodInfo mi = Importer.GetType().GetMethod("ImportExcel");//先获取到DisplayType<T>的MethodInfo反射对象
            var ob = await(dynamic)mi.MakeGenericMethod(new Type[] { obj.GetType() }).Invoke(Importer, new object[] { "C:\\Users\\keying\\Desktop\\导入模板.xlsx", null, null });//然后使用MethodInfo反射对象调用ReflectionTest类的DisplayType<T>方法,这时要使用MethodInfo的MakeGenericMethod函数指定函数DisplayType<T>的泛型类型T
                                                                                                                                                                                      //var importDic = Importer.Import<int>("C:\\Users\\keying\\Desktop\\导入模板.xlsx").Result;
            Console.WriteLine(JsonSerializer.Serialize(ob.Data));
        }


        public static IEnumerable<KeyValuePair<string, object>> GetTypeValues<T>(T typeObject) where T : class
        {
            // typeObject specific operations
            IEnumerable<KeyValuePair<string, object>> typeValues =
                typeObject
                .GetType()
                .GetProperties()
                .Select(property => new KeyValuePair<string, object>(property.Name, property.GetValue(typeObject)));
            return typeValues;
        }
    }
}

posted on 2023-06-06 20:19  隨風.NET  阅读(27)  评论(0编辑  收藏  举报

导航