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]
.NET 7 환경에서 테스트 해봤는데 잘 동작합니다^^
참고한 사이트
https://www.sysnet.pe.kr/2/0/12809
728x90
그리드형
'C#' 카테고리의 다른 글
[C#] Swagger 분석하기 (0) | 2023.05.12 |
---|---|
[C#] C# Code Editor - roslynpad (0) | 2023.05.10 |
[C#/Rendezvous] 에러 - "TIBCO.Rendezvous.netmodule" cannot be found (0) | 2023.05.03 |
[C#] euc-kr 인코딩 에러 - No data is available for encoding 51949. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. (0) | 2023.05.03 |
[C#] Tibco Rendezvous 처리하기 (0) | 2023.04.28 |