Skip to content
H1Gdev edited this page Jun 13, 2022 · 23 revisions

Nuget

.NET API browser - Roslyn

Packages

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;

Source code

var source = @"
using System;

namespace ConsoleApp
{
    internal class Program
    {
        static void Main()
        {
            Console.WriteLine(""Hello, World!"");
        }
    }
}
";
var sourceText = SourceText.From(source, System.Text.Encoding.UTF8);

var options = CSharpParseOptions.Default
    .WithLanguageVersion(LanguageVersion.LatestMajor);

var syntaxTree = CSharpSyntaxTree.ParseText(
#if false
    // use string.
    source,
#else
    // use SourceText.
    sourceText,
#endif
    options
)
    .WithFilePath(Path.Combine(sourcePath, "Program.cs"));

Reference

var runtimeDirectoryPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
var references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "mscorlib.dll")),
    MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Runtime.dll")),
    // add References if needed.
    MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Console.dll")),
};
// target framework depends on using libraries.
var entryAssemblyPath = System.Reflection.Assembly.GetEntryAssembly()?.Location ?? string.Empty;
var callingAssemblyPath = System.Reflection.Assembly.GetCallingAssembly()?.Location ?? string.Empty;
var executingAssemblyPath = System.Reflection.Assembly.GetExecutingAssembly()?.Location ?? string.Empty;

Build

var compilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication)
    .WithOptimizationLevel(OptimizationLevel.Release)
    // if needed.
    .WithUsings(new[] { "System.IO" }); // used only in scripting ??

var compilation = CSharpCompilation.Create(
    "ConsoleApp",
    // source code(s).
    new[] { syntaxTree },
    references,
    compilationOptions);

On File

var assemblyFile = $"{compilation.AssemblyName}.{(compilationOptions.OutputKind == OutputKind.ConsoleApplication ? "exe" : "dll")}";
var assemblyPath = Path.Combine(buildPath, assemblyFile);
var emitResult = compilation.Emit(assemblyPath);

On Memory

using var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);

Result

foreach (var diagnostic in emitResult.Diagnostics)
{
#if false
    var pos = diagnostic.Location.GetLineSpan();
    var location = $"{pos.Path}({pos.StartLinePosition.Line + 1},{pos.StartLinePosition.Character + 1})";
    Console.WriteLine($"{location}: {diagnostic.Severity} {diagnostic.Id}: {diagnostic.GetMessage()}");
#else
    // use DiagnosticFormatter internally.
    Console.WriteLine(diagnostic);
#endif
}

if (!emitResult.Success)
    throw new InvalidProgramException("Compile error occured.");

Run

Packages

using System.Reflection;
#if !NETFRAMEWORK
using System.Runtime.Loader;
#endif

On File

#if NETFRAMEWORK
var assembly = Assembly.LoadFrom(assemblyPath);
#else
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
#endif

On Memory

stream.Seek(0, SeekOrigin.Begin);
#if NETFRAMEWORK
var assembly = Assembly.Load(stream.ToArray());
#else
var assembly = AssemblyLoadContext.Default.LoadFromStream(stream);
#endif

Context

#if !NETFRAMEWORK
var assemblyLoadContext = new AssemblyLoadContext(compilation.AssemblyName, true);

try
{
    // load from assemblyLoadContext.
}
finally
{
    assemblyLoadContext.Unload();
}
#endif
  • If unload assembly.

Run

var type = assembly.GetType("ConsoleApp.Program");
var method = type?.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
method?.Invoke(null, null);
Clone this wiki locally