passing class types to runtime compiled code C#

389 views Asked by At

I am trying to read and compile an external file (it's in a string constant for now)

I can use basic primitives in the external code but I can't seem to figure out how to pass it a class type without it getting angry -heres what I have (excluding the using lines)

class myClass
{
    public int x;
    public myClass(int n)
    {
        x = n;
    }
}
class Program
{
    static void Main(string[] args)
    {
        string source =
        @"
           namespace ConsoleApplication1
           {
               public class Bar
               {
                   public int getNumber(myClass c)
                   {
                       return c.x;
                   }
              }
          }";     
            Dictionary<string, string> providerOptions = new Dictionary<string, string>
            {
                {"CompilerVersion", "v3.5"}
            };
            CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
            CompilerParameters compilerParams = new CompilerParameters
            {
                GenerateInMemory = true,
                GenerateExecutable = false
            };
            CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);
            if (results.Errors.Count != 0)
                throw new Exception("Failed");
        object o = results.CompiledAssembly.CreateInstance("ConsoleApplication1.Bar");
        MethodInfo mi = o.GetType().GetMethod("getNumber");
        object[] param = new object[1];
        myClass c = new myClass(5);
        param[0] = c;
        int myInt = (int)mi.Invoke(o, param);
        Console.Write(myInt);
        Console.ReadLine();
    }
}

Help would be appreciated

1

There are 1 answers

0
Mike Cheel On

When I looked at your code it appears the problem is that your 'new' assembly (the string version) does not know about the currently executing assembly (same namespace or not). The solution is to reference the currently executing assembly. Add this line right after your compilerParams initialization:

compilerParams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

Also, when I fired up your code I changed the myClass declaration to public.