动态生成类并通过反射调用
动态生成类并通过反射调用
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;
}
}
}