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);