1

I have a requirement of executing a C# class in the string format and populate an object with the properties of that class. To achieve the requirement I was doing a POC and that's failed.

Following code is failing to evaluate where i was trying to update the input model.

Program.cs

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

namespace CSCodeExecuter
{
    class Program
    {
        static void Main(string[] args)
        {
            Model input = new Model();
            string scriptId = "123";
            ScriptManager sriptMgr = new ScriptManager();
            sriptMgr.ExecuteScript<Model>(scriptId, ref input);

            Console.WriteLine(input.ToString());
            Console.ReadKey();
        }
    }
}

ScriptManager.cs

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSCodeExecuter
{
    public class ScriptManager
    {
        public void ExecuteScript<T>(string scriptId, ref T input)
        {
            try
            {
                string inputSript = GetStriptById(scriptId);
                var scriptOptions = ScriptOptions.Default;
                scriptOptions.AddReferences("CSCodeExecuter");
                
                Execute(inputSript, scriptOptions);
                var result = Execute("new ScriptedClass().input", scriptOptions);
            }
            catch (Exception ex)
            {
                throw;
            }
            
        }

        private string GetStriptById(string id)
        {
  
            string csSript = @" public class ScriptedClass
            {
                public CSCodeExecuter.Model input {get;set;}
                public void ScriptedClass()
                {
                   {" + GetInternalScript() + @"}
                }
            }";

            return csSript;
        }

        private string GetInternalScript()
        {
            return "input.Id = \"1111\"; " + "input.Name = \"test\"; " + "input.Phone = \"1234567890\"; ";
        }


        private static ScriptState<object> scriptState = null;
        public static object Execute(string code, dynamic scriptOptions)
        {
            scriptState = scriptState == null ? CSharpScript.RunAsync(code).Result : scriptState.ContinueWithAsync(code).Result;

            if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
                return scriptState.ReturnValue;
            return null;
        }
    }
}

Model.CS

namespace CSCodeExecuter
{
    public class Model
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Phone { get; set; }
    }
}


1
  • If my answer helped you please mark it as correct (green check mark).Thank you and good luck. Commented Mar 25, 2021 at 14:13

1 Answer 1

2

Now it works:

using System;

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

namespace CSCodeExecuter
{
    public class ScriptManager
    {
        public void ExecuteScript<T>(string scriptId, ref T input)
        {
            try
            {
                string inputSript = GetStriptById(scriptId);
                var scriptOptions = ScriptOptions.Default.AddReferences("CSCodeExecuter");

                var result = Execute(inputSript, scriptOptions);
            }
            catch (Exception ex)
            {
                throw;
            }

        }

        private string GetStriptById(string id)
        {

            string csSript =
                @"
                public class ScriptedClass
                {
                    public CSCodeExecuter.Model input {get;set;}
                    public ScriptedClass()
                    {
                        " + GetInternalScript() + @"
                    }
                }

                return (new ScriptedClass()).input;";

            return csSript;
        }

        private string GetInternalScript()
        {
            return "input = new CSCodeExecuter.Model(); input.Id = \"1111\"; input.Name = \"test\"; input.Phone = \"1234567890\"; ";
        }


        private static ScriptState<object> scriptState = null;
        public static object Execute(string code, dynamic scriptOptions)
        {
            scriptState = scriptState == null ? CSharpScript.RunAsync(code, scriptOptions).Result : scriptState.ContinueWithAsync(code).Result;

            if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
                return scriptState.ReturnValue;
            return null;
        }
    }
}

You had several errors:

  1. not use options(second parameter) in Execute
  2. extra parentheses in ctor
  3. ctor should not has a result type(void)
  4. input property was not initialized
  5. scripts with creating of class and using of it was separated
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.