Roslyn - Create MetadataReference from in-memory assembly
It's been a while but I did get an answer this on github Roslyn repository so I'll post it in case someone finds this question:
ASP.NET 5 has an API for this. You can do what Razor does https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs#L132
This was back in around Beta1 of Asp.Net 5 so may need tweaking but the principle is still the same - follow the API that Asp.Net itself uses via the IAssemblyLoadContextAccessor
which the service injector will provide.
Thanks to David Fowler
UPDATE: This answer was for ASP.NET 5 Beta1. The API has changed a lot, and in Core 1.0 instead of using IAssemblyLoadContextAccessor, you can access AssemblyLoadContext from the static member:
System.Runtime.Loader.AssemblyLoadContext.Default
And you can then call LoadFromStream to load an assembly from a binary image. Here is a very rough sketch of the code I use with some irrelevant bits hacked out:
// Give the assembly a unique name
var assemblyName = "Gen" + Guid.NewGuid().ToString().Replace("-", "") + ".dll";
// Build the syntax tree
var syntaxTree = CSharpSyntaxTree.ParseText(source);
// Compile the code
var compilation = CSharpCompilation.Create(
assemblyName,
options: new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary),
syntaxTrees: new List<SyntaxTree> { syntaxTree },
references: GetMetadataReferences());
// Emit the image of this assembly
byte[] image = null;
using (var ms = new MemoryStream())
{
var emitResult = compilation.Emit(ms);
if (!emitResult.Success)
{
throw new InvalidOperationException();
}
image = ms.ToArray();
}
Assembly assembly = null;
// NETCORE
using (var stream = new MemoryStream(image))
assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(stream);
This is not supposed to run as is, but just give an idea of the main steps.
Also the issue with generating metadata references from an in-memory only assembly no longer exists as these no longer exist in Core 1.0, so every Assembly has a Location property. So getting these references is basically the same process as in ASP.net 4:
MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName(assemblyName)).Location);