C# Scripting – Dynamic code execution

When using C# scripting and code reflection in .NET Framework, libraries needs to be loaded with “ScriptOptions” from Microsoft.CodeAnalysis.Scripting. This has to be done before code executes with function ScriptOptions.Default.AddReferences(). Note that this is different from dynamic code execution via Roslyn.

net logo

Sample code for .NET Framework (v.6):

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.Collections.Generic;

    public class Exec
    {
        static string lastCode = null;
        public void ExecFunction(string code)
        {
            try
            {
                if (string.IsNullOrEmpty(lastCode) || lastCode.Equals(code))
                {
                    lastCode = code;
                    code = code.Replace("\r\n", " ");

                    var elems = code.Split(';');
                    int usingEndIndex = 0;

                    //Process using directives
                    var libsList = new List<string>();

                    for (int i = 0; i < elems.Length; i++)
                    {
                        elems[i] = elems[i].Trim();
                        if (elems[i].StartsWith("using"))
                        {
                            var lib = elems[i].Split(' ');
                            if (lib.Length == 2)
                            {
                                if (!string.IsNullOrEmpty(lib[1]) && lib[1].Length > 0)
                                {
                                    libsList.Add(lib[1]);
                                }
                            }
                        }
                        else
                        {
                            usingEndIndex = i;
                            break;
                        }
                    }

                    //Add libs
                    ScriptOptions options = ScriptOptions.Default;
                    if (libsList.Count > 0)
                    {
                        options = ScriptOptions.Default.AddReferences(typeof(System.Linq.Enumerable).Assembly).WithImports(libsList);
                    }

                    //Process src code
                    string srcCode = string.Empty;
                    for (int i = usingEndIndex; i < elems.Length; i++)
                    {
                        srcCode += elems[i];
                    }

                    CSharpScript.RunAsync(srcCode, options).Wait();
                    lastCode = code;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Duplicated code fetch! Ignore..");
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error in code execution!\r\n\r\n" + e.ToString());
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.