728x90
728x170

C# 코드를 작성하면 빌드하여 내부 메서드를 호출할 수 있도록 C# 코드 Compiler 구현하는 방법입니다.

1. Microsoft.CodeAnalysis.CSharp 패키지를 설치합니다.

2. 컴파일할 코드를 준비합니다.

using System;

public class Function
{
    public double Plus(double a, double b)
    {
        return a + b;
    }
}

3. 위 코드가 동작하도록 컴파일러를 통해 컴파일하고 해당 Type의 Method를 호출합니다.

using System.Reflection;
using System.Runtime.Loader;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;

string code = @"
using System;

public class Function
{
    public double Plus(double a, double b)
    {
        return a + b;
    }
}";

string assemblyName = "Test";

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);

var refPaths = new[] {
                typeof(System.Object).GetTypeInfo().Assembly.Location,
                typeof(Console).GetTypeInfo().Assembly.Location,
                Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll")};

MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();

CSharpCompilationOptions options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

CSharpCompilation compilation = CSharpCompilation.Create(
    assemblyName,
    syntaxTrees: new[] { syntaxTree },
    references: references,
    options: options);

using (var ms = new MemoryStream())
{
    EmitResult result = compilation.Emit(ms);

    if (result.Success)
    {
        ms.Seek(0, SeekOrigin.Begin);

        Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
        var type = assembly.GetType("Function");
        var instance = assembly.CreateInstance("Function");

        if (type != null)
        {
            var method = type.GetMember("Plus").First() as MethodInfo;

            if (method != null)
            {
                var methodResult = method.Invoke(instance, new object[] { 3, 4 });
            }
        }
    }
}

 

결과

[Source]

CompileTest.zip
0.09MB

 

.NET 7 환경에서 테스트 해봤는데 잘 동작합니다^^

 

참고한 사이트
https://www.sysnet.pe.kr/2/0/12809

 

.NET Framework: 1106. .NET Core/5+에서 C# 코드를 동적으로 컴파일/사용하는 방법

글쓴 사람 정성태 (techsharer at outlook.com) 홈페이지 첨부 파일 [cs_roslyn_compile_src.zip]     부모글 보이기/감추기 (연관된 글이 2개 있습니다.) .NET Core/5+에서 C# 코드를 동적으로 컴파일/사용하는 방법

www.sysnet.pe.kr

 

728x90
그리드형
Posted by kjun
,