Clever-1945
12/1/2017 - 4:59 AM

Выполнение кода из строки #CSharp

Выполнение кода из строки #CSharp

//В тексте строки, основной класс должен быть унаследован от интерфейса IRunable

string source =
            @"using System;
            namespace ScriptCode
            {
                public class MyClass: ScriptRun.IRunable
                {
                    public string MyMethod(string _value)
                    {
                        return ""метод MyMethod: return string value: _value = "" + _value;
                    }
                    public void Run()
                    {
                        Console.WriteLine(""Text from script"");
                        Console.WriteLine(DateTime.Now.ToString());
                        
                    }
                }
            }
            ";

            ScriptEngine.RunScript(source);
            Console.ReadKey();
            
            
//Интерфейс IRunable\
public interface IRunable
    {
        void Run();
    }


//Класс ScriptEngine
public class ScriptEngine
    {
        private CompilerResults Results = null;
        public void Compile(string _source, string[] _assemblies)
        {
            CompilerParameters compilerParameters = new CompilerParameters();
            compilerParameters.GenerateInMemory = true;
            if (_assemblies != null)
            {
                foreach (string asm in _assemblies)
                {
                    compilerParameters.ReferencedAssemblies.Add(asm);
                }
            }

            Results = new CSharpCodeProvider()
                .CompileAssemblyFromSource(compilerParameters, _source);

            if (Results.Errors.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < Results.Errors.Count; i++)
                {
                    sb.Append(Results.Errors[i].ToString());
                }
                throw new InvalidOperationException(sb.ToString());
            }
        }

        public IRunable CreateClass()
        {
            var runable = Results.CompiledAssembly.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(IRunable))).FirstOrDefault();
            if (runable == null)
                return null;

            return Results.CompiledAssembly.CreateInstance(runable.Namespace + "." + runable.Name) as IRunable;
        }

        public static void RunScript(string script)
        {
            ScriptEngine engine = new ScriptEngine();
            engine.Compile(script, new string[] { Assembly.GetExecutingAssembly().Location });

            engine.CreateClass().Run();
        }
    }