Both previous answers didn't work for me in a .NET Core 2.2 environment on Windows. More references are needed.
So with the help of the https://mcmap.net/q/662252/-net-core-amd-roslyn-csharpcompilation-the-type-39-object-39-is-defined-in-an-assembly-that-is-not-referenced solution, I have ended up with this code:
var dotnetCoreDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
var compilation = CSharpCompilation.Create("LibraryName")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(Path.Combine(dotnetCoreDirectory, "mscorlib.dll")),
MetadataReference.CreateFromFile(Path.Combine(dotnetCoreDirectory, "netstandard.dll")),
MetadataReference.CreateFromFile(Path.Combine(dotnetCoreDirectory, "System.Runtime.dll")))
.AddSyntaxTrees(CSharpSyntaxTree.ParseText(
@"public static class ClassName
{
public static void MethodName() => System.Console.WriteLine(""Hello C# Compilation."");
}"));
// Debug output. In case your environment is different it may show some messages.
foreach (var compilerMessage in compilation.GetDiagnostics())
Console.WriteLine(compilerMessage);
Than output library to file:
var fileName = "LibraryName.dll";
var emitResult = compilation.Emit(fileName);
if (emitResult.Success)
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(fileName));
assembly.GetType("ClassName").GetMethod("MethodName").Invoke(null, null);
}
or to memory stream:
using (var memoryStream = new MemoryStream())
{
var emitResult = compilation.Emit(memoryStream);
if (emitResult.Success)
{
memoryStream.Seek(0, SeekOrigin.Begin);
var context = AssemblyLoadContext.Default;
var assembly = context.LoadFromStream(memoryStream);
assembly.GetType("ClassName").GetMethod("MethodName").Invoke(null, null);
}
}