728x90
728x170
▶ Program.cs
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
Console.Title = "CSharpCompilation 클래스 : 런타임에서 C# 코드를 동적으로 컴파일하기";
#region C# 코드를 설정한다.
string code = @"
using System;
namespace TestProject
{
public class Writer
{
public void Write(string message)
{
Console.WriteLine(message);
}
}
}
";
#endregion
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
string assemblyName = Path.GetRandomFileName();
MetadataReference[] referenceArray = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location)
};
CSharpCompilation compilation = CSharpCompilation.Create
(
assemblyName,
syntaxTrees : new[] { syntaxTree },
references : referenceArray,
options : new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
using(MemoryStream stream = new MemoryStream())
{
EmitResult result = compilation.Emit(stream);
if(!result.Success)
{
IEnumerable<Diagnostic> diagnosticEnumerable = result.Diagnostics.Where
(
diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error
);
foreach(Diagnostic diagnostic in diagnosticEnumerable)
{
Console.Error.WriteLine("{0} : {1}", diagnostic.Id, diagnostic.GetMessage());
}
}
else
{
stream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(stream.ToArray());
Type type = assembly.GetType("TestProject.Writer");
object instance = Activator.CreateInstance(type);
type.InvokeMember
(
"Write",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
instance,
new object[] { "Hello World" }
);
}
}
Console.ReadLine();
}
#endregion
}
}
※ .NET 4.6 버전 이상에서 지원한다.
728x90
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 너비 우선 탐색을 사용해 최단 경로 구하기 (0) | 2018.04.28 |
---|---|
[C#/COMMON] 너비 우선 탐색하기 (Breadth-First Search) (0) | 2018.04.28 |
[C#/COMMON] 깊이 우선 탐색하기 (Depth-First Search) (0) | 2018.04.28 |
[C#/COMMON] 런타임에서 코드로 C# 코드 생성하기 (0) | 2018.04.26 |
[C#/COMMON] CodeDomProvider 클래스 : 런타임에서 C# 코드를 동적으로 컴파일하고 DLL 파일 생성하기 (0) | 2018.04.26 |
[C#/COMMON] Stream 클래스 : 스로틀(Throttle) 스트림 만들기 (0) | 2018.04.09 |
[C#/COMMON] 특정 파일을 사용하는 프로세스 리스트 구하기 (0) | 2018.03.29 |
[C#/COMMON] 사용자 계정 변경하기 (0) | 2018.03.24 |
[C#/COMMON] 콘솔(Console) 닫기 버튼 비활성화 하기 (0) | 2018.03.22 |
[C#/COMMON] 디버그 모드에서 프로세스 참조 구하기 (0) | 2018.03.15 |