Compiling and Running code at runtime in .Net Core 1.0

后端 未结 3 548
再見小時候
再見小時候 2020-12-03 03:39

Is it possible to compile and run C# code at runtime in the new .Net Core (better .Net Standard Platform)? I have seen some examples (.Net Framework), but they used NuGet pa

3条回答
  •  一向
    一向 (楼主)
    2020-12-03 04:12

    Just adding to @svick option one answer. If you want to keep the assembly in memory (rather than writing to a file) you can use the following method:

    AssemblyLoadContext context = AssemblyLoadContext.Default;
    Assembly assembly = context.LoadFromStream(ms);
    

    This is different that in Net451 where the code is:

    Assembly assembly = Assembly.Load(ms.ToArray());
    

    My code targets both Net451 and Netstandard so I had to use directives to get around this problem. The full code example is here:

                       string code = CreateFunctionCode();
                        var syntaxTree = CSharpSyntaxTree.ParseText(code);
    
                        MetadataReference[] references = new MetadataReference[]
                        {
                            MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
                            MetadataReference.CreateFromFile(typeof(Hashtable).GetTypeInfo().Assembly.Location)
                        }; 
    
                         var compilation = CSharpCompilation.Create("Function.dll",
                            syntaxTrees: new[] { syntaxTree },
                            references: references,
                            options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    
                        StringBuilder message = new StringBuilder();
    
                        using (var ms = new MemoryStream())
                        {
                            EmitResult result = compilation.Emit(ms);
    
                            if (!result.Success)
                            {
                                IEnumerable failures = result.Diagnostics.Where(diagnostic =>
                                    diagnostic.IsWarningAsError ||
                                    diagnostic.Severity == DiagnosticSeverity.Error);
    
                                foreach (Diagnostic diagnostic in failures)
                                {
                                    message.AppendFormat("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                                }
    
                                return new ReturnValue(false, "The following compile errors were encountered: " + message.ToString(), null);
                            }
                            else
                            {
    
                                ms.Seek(0, SeekOrigin.Begin);
    
     #if NET451
                                Assembly assembly = Assembly.Load(ms.ToArray());
     #else
                                AssemblyLoadContext context = AssemblyLoadContext.Default;
                                Assembly assembly = context.LoadFromStream(ms);
     #endif
    
                                Type mappingFunction = assembly.GetType("Program");
                                _functionMethod = mappingFunction.GetMethod("CustomFunction");
                                _resetMethod = mappingFunction.GetMethod("Reset");
                            }
                        }
    

提交回复
热议问题