首页 > 其他分享 >动态生成类并通过反射调用

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

时间:2023-06-06 20:33:16浏览次数:51  
标签:反射 调用 Console System 生成 item WriteLine var using

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

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;
        }
    }
}

标签:反射,调用,Console,System,生成,item,WriteLine,var,using
From: https://www.cnblogs.com/xinzhyu/p/17461636.html

相关文章

  • HttpURLConnection调用webservice,c#、java、python等HTTP调用webservice,简单的webserv
    以前调用webservice一般使用axis、axis2先生成java类后,直接引用,多方便。但是有的webservice接口非常的函数,生成的java类非常多,有没有一种非常简化的方法。axis2有不生成类直接调用的方法,但是QName不容易找,每次查N久不到。有的反馈,使用CXF调用一样方便,但CXF还要使用maven下载jar,而......
  • .Net6 调用qq邮箱发送邮件
    1.appsettings.json写入需要用到的基本信息 2.发送消息核心方法publicclassSendHelperl{privatereadonlyIConfiguration_configuration;publicSendHelperl(IConfigurationconfiguration){_configuration=configura......
  • API接口对电商平台的实质性帮助有哪些?以及api接口调用的的方式|根据关键词取商品列表
    API接口提供了电商平台之间数据和功能的交互方式,可以为电商平台带来以下几方面的实质性帮助:1. 增加平台数据实时性和准确性:通过API接口实现两个电商平台数据的实时同步,保证了平台商品信息、订单信息等数据的实时性和准确性。2. 提升平台的扩展性和可拓展性:通过API接口,第三方开......
  • Swagger2生成Api文档
    前置条件是项目中已经使用swagger一、html格式:1.加入依赖swagger2markup<!--文档生成--> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup</artifactId> <version>1.3.1</ve......
  • Java 匿名内部类调用局部变量
    Java8之前,匿名内部类中使用局部变量,需要强制使用final修饰Java8开始匿名内部类使用的外部变量不再被强制用final修饰。外部变量要么是final的;要么自初始化后值不会被改变这两种都是可以在匿名内部类中使用且编译通过。但是java8只是对‘事实上final’变量可以不声明final标......
  • 生成器
    生成器生成器的定义:在函数里面具有yield关键字的函数就是生成器。生成器的作用:节省了内存空间在调用函数的时候就不会执行函数体代码了,变成了生成器。"""生成器其实也是迭代器"""defindex():print('first')yieldprint('second')res=index()......
  • javasecript 生成 从2022年到当前季度的所以季度,排倒序
    javasecript 生成从2022年到当前季度的所以季度,排倒序 functiongetQuarter(year,quarter){returnyear+"年"+quarter+"季度";}functiongenerateQuarters(){varcurrentYear=newDate().getFullYear();varcurrentQuarter=Math.floor((......
  • Java-模板生成PDF方式3-HtmlToPDF
    使用thymeleaf做html模板,由xhtmlrenderer/flying-saucer-pdf-openpdf将html转为PDFLGPL和MPL许可pom.xml引入依赖<!--thymeleaf模板引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spri......
  • Java-模板生成PDF方式2-PDFBox
    PDFBox文本域+内容流生成PDFBSD许可下的源码开放项目pom.xml引入依赖<!--pdfbox生成PDF--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version>......
  • Java-模板生成PDF方式1-itext5
    itext模板生成PDFpom.xml引入依赖<!--itext生成PDF--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency><!--输出中文--><dep......