.Net Core -源代码动态编译

一、新建项目JIT

Nuget:

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
  </ItemGroup>

核心代码:WeatherForecastController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.CodeDom.Compiler;
using System.Diagnostics;
using Microsoft.CSharp;
using JIT.Models;
using System;
using JIT.Common;
using System.IO;
using System.Reflection;
using System.Linq;

namespace JIT.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public ActionResult Get()
        {

            var person = new Person<Son1>();
            person.Son = new Son1 { Name = "OK" };
            var name = person.GetName();

            TestReflection();

            TestCompile();

            return Ok(true);
        }

        private void TestReflection()
        {
            //获取泛型
            var personTypeG = this.GetType().Assembly.GetType("JIT.Models.Person`1");

            //创建指定泛型参数实例
            var personType = personTypeG.MakeGenericType(this.GetType().Assembly.GetType("JIT.Models.Son1"));

            //创建Son1实例
            var sonC = Activator.CreateInstance(this.GetType().Assembly.FullName, "JIT.Models.Son1").Unwrap();
            var personC = Activator.CreateInstance(personType);

            //赋值
            sonC.GetType().GetProperty("Name").SetValue(sonC, "hi");
            personC.GetType().GetProperty("Son").SetValue(personC, sonC);

            //输出
            var myName = personC.GetType().GetMethod("GetName").Invoke(personC, new object[] { });
        }

        private void TestCompile()
        {
            var compiler = new Compiler();
            var codes = System.IO.File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Sources/CompileCodes.txt"));
            CompileCodes(compiler, codes);
            codes = System.IO.File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Sources/CompileCodes2.txt"));
            CompileCodes(compiler, codes);
        }

        private static void CompileCodes(Compiler compiler, string codes)
        {
            var referencedAssemblies = new Assembly[] {
                Assembly.Load(new AssemblyName("System")) ,
                Assembly.Load(new AssemblyName("System.Linq")),
                Assembly.Load(new AssemblyName("System.Threading.Tasks")),
                typeof(object).Assembly
            };

            var assembly = compiler.Compile(codes, referencedAssemblies);

            //获取泛型
            var personTypeG = assembly.GetType("JIT.Models.PersonCompile`1");

            //创建指定泛型参数实例
            var personType = personTypeG.MakeGenericType(assembly.GetType("JIT.Models.SonCompile1"));

            var type = assembly.GetExportedTypes().Where(p => p.FullName == "JIT.Models.SonCompile1").SingleOrDefault();

            //创建Son1实例
            var sonC = Activator.CreateInstance(type);
            var personC = Activator.CreateInstance(personType);

            //赋值
            sonC.GetType().GetProperty("Name").SetValue(sonC, "hi");
            personC.GetType().GetProperty("Son").SetValue(personC, sonC);

            //输出
            var myName = personC.GetType().GetMethod("GetName").Invoke(personC, new object[] { });
        }
    }
}

下载地址:

上一篇:每天一个linux命令(33)--du命令


下一篇:flex布局justify-content发现