I'm developing a .Net Standard 2.0 library offering dynamic compilation but there are always missing references.
A consumer using .Net Core, calls an Api with his source code as text, implementing a known interface by the library.
//Consumer Program.cs
using DynamicCompilationNetStandard2._0;
var source = """
using DynamicCompilationNetStandard2._0;
using System.Linq.Expressions;
namespace Consumer
{
public class MyTask : ITask
{
public void CanRun<T>(Expression<Func<T, bool>> predicate)
{
}
public void Run()
{
Console.WriteLine("Finished");
}
}
}
""";
Executor.Execute(source);
The library's Executor
class:
using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using System.Linq.Expressions;
namespace DynamicCompilationNetStandard2._0;
public static class Executor
{
public static void Execute(string source)
{
var syntaxTree = SyntaxFactory.ParseSyntaxTree(source);
var compilation = CSharpCompilation.Create(assemblyName: Path.GetRandomFileName())
.WithReferenceAssemblies(ReferenceAssemblyKind.NetStandard20)
.AddReferences(
MetadataReference.CreateFromFile(typeof(ITask).Assembly.Location))
.AddReferences(ReferenceAssemblies.NetStandard20)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddSyntaxTrees(syntaxTree);
using (var ms = new MemoryStream())
{
var result = compilation.Emit(ms);
if (!result.Success)
{
throw new Exception(result.ToString()); //CRASH
}
ms.Seek(0, SeekOrigin.Begin);
var assembly = Assembly.Load(ms.ToArray());
try
{
var types = assembly.GetTypes();
}
catch (Exception ex)
{
throw; //CRASH
}
dynamic task = assembly.CreateInstance("Consumer.MyTask");
task.Run();
}
}
}
public interface ITask
{
void CanRun<T>(Expression<Func<T, bool>> predicate);
void Run();
}
I'm using basic-reference-assemblies to add references to reference assemblies instead of implementations. Still I get theses errors:
How can I import missing references and fixing this simple project? Here is the source code: https://github.com/adampaquette/DynamicCompilationTests Thanks!
Ok the problem was an implicit reference to System. After adding using System;
in the source string, it worked.