2

I am trying to use JSON in a dynamically compiled script. However, when I include the library and add a JObject, I get errors like: "The type 'System.Dynamic.IDynamicMetaObjectProvider' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'."

I included MathNet.Numerics just fine.

Here is my setup.

  • Console application .NET Framework 4 (so it matches the runtime compile)
  • Nuget install MathNet.Numerics
  • Nuget install Newtonsoft
  • Point the runtime compile to the debug folder with the dlls.

Test Code

using System;
using System.IO;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Microsoft.CSharp;
using System.Reflection;
using System.CodeDom.Compiler;

namespace ConsoleApp1
{

  public class RunScript0
  {


    public bool Compile()
    {

      //Add using statements here
      string source = "namespace UserScript\r\n{\r\nusing System;\r\n" +
                "using System.IO;\r\n" +
                "using System.Collections.Generic;\r\n" +
                "using MathNet.Numerics.Distributions;\r\n" +
                "using Newtonsoft.Json.Linq;\r\n" +
                "using Newtonsoft.Json;\r\n" +
                "public class RunScript\r\n{\r\n" +
                "private const int x = 99;\r\n" +
                "public int Eval()\r\n{\r\n" +
                //Remove following line and all works fine
                "JObject j = new JObject();\r\n" +
                "return x; \r\n\r\n}\r\n}\r\n}";

      Dictionary<string, string> provOptions =
        new Dictionary<string, string>();

      provOptions.Add("CompilerVersion", "v4.0");
      CodeDomProvider compiler = new CSharpCodeProvider(provOptions);


      CompilerParameters parameters = new CompilerParameters();
      string appPath = System.IO.Directory.GetCurrentDirectory();
      parameters.ReferencedAssemblies.Add(appPath + "\\MathNet.Numerics.dll");
      parameters.ReferencedAssemblies.Add(appPath + "\\Newtonsoft.Json.dll");
      //Tried adding but didn't help parameters.ReferencedAssemblies.Add(appPath + "\\System.Core.dll");

      parameters.GenerateInMemory = true;
      var results = compiler.CompileAssemblyFromSource(parameters, source);
      // Check for compile errors / warnings
      if (results.Errors.HasErrors || results.Errors.HasWarnings)
      {
        Console.WriteLine(results.Errors.Count.ToString() + " Erorrs");
        for (int i = 0; i < results.Errors.Count; i++)
          Console.WriteLine(results.Errors[i].ToString());
        return false;
      }
      else
      {
        Console.WriteLine("Compiled Successfully");
        return true;
      }
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      RunScript0 A = new RunScript0();
      A.Compile();
    }
  }
}
runfastman
  • 927
  • 2
  • 11
  • 31
  • What .NET version do you use to compile? – vernou Aug 10 '20 at 16:02
  • I believe it is 4.0 as shown in the code - provOptions.Add("CompilerVersion", "v4.0"); or were you meaning something else? – runfastman Aug 11 '20 at 17:36
  • My question is for the .Net version of all code (not the meta code). – vernou Aug 12 '20 at 07:02
  • Project Target Framwork = .Net Framework 4. I selected this one ato match the meta compile "v4.0", this way any dlls in the exe directory would be the right versions and could be referenced in the meta code. – runfastman Aug 12 '20 at 14:03

1 Answers1

0

You need add a reference to System and System.Core from the GAC (Global Assembly Cache) :

parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");

I think it's dependances from Newtonsoft.Json.

vernou
  • 6,818
  • 5
  • 30
  • 58
  • It doesn't list those in the dependencies in Nuget. – runfastman Aug 13 '20 at 17:40
  • Strange, your suggestion worked on my test application, but in my real one I get other errors. I copied the exact same code and dlls under a test function and the first error I get is - The type 'System.Dynamic.IDynamicMetaObjectProvider' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. If I add the dotstandard.dll like the system.dll then I get a ton of "defined in multiple assemblies" – runfastman Aug 13 '20 at 17:41
  • Maybe this : https://stackoverflow.com/a/1020547/2703673 – vernou Aug 13 '20 at 20:25
  • Thanks I wish I would have seen this before. The loop and addRange example in there was perfect. – runfastman Aug 14 '20 at 21:53