1

I have a .NET application that can take a script written in C# and executes it internally. The scripts are parsed by the class listed below and then compiled. I find that whenever I try and use System.Xml.Linq in the C# script that is compiled I get a compile error and I am not sure why.

public static void CreateFunction(string scriptCode, BO.ObjectBO obj)
{
    CSharpCodeProvider provider = new CSharpCodeProvider();
    CompilerParameters options = new CompilerParameters();
    options.ReferencedAssemblies.Add("System.Data.dll");
    options.ReferencedAssemblies.Add("System.dll");
    options.ReferencedAssemblies.Add("System.Xml.dll");
    options.ReferencedAssemblies.Add("System.Linq.dll");
    options.ReferencedAssemblies.Add("System.Xml.Linq.dll");

    options.GenerateExecutable = false;
    options.GenerateInMemory = true;
    CompilerResults results = provider.CompileAssemblyFromSource(options, scriptCode);

    _errors = results.Errors;

    if (results.Errors.HasErrors)
    {
        DataTable errorTable = BO.DataTableBO.ErrorTable();
        foreach(CompilerError err in results.Errors)
        {
           DataRow dr = errorTable.NewRow();
           dr["ErrorMessage"] = "Line "+ err.ErrorNumber.ToString() + " " + err.ErrorText;
           errorTable.Rows.Add(dr);
         }
        return;
    }

    Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");

    _methodInfo = binaryFunction.GetMethod("Function");
}

Here is the error message I get when I try and run a script that makes use of LINQ extensions inside the compiler.

'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' could be found (are you missing a using directive or an assembly reference?)

Does anyone see what I may be doing wrong? I am attempting to include System.Linq and System.Xml.Linq yet the compiler does not seem to be able to locate them.

Here is an example C# script I am trying to compile that makes use of LINQ extensions.

using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;

namespace CompilerTest
{
  public class BinaryFunction
  {
    public static void Function()
    {
      string xmlData = @"<data>
                          <clients>
                            <client>
                              <clientId>1</clientId>
                              <clientName>Dell</clientName>
                            </client>
                            <client>
                              <clientId>2</clientId>
                              <clientName>Apple</clientName>
                            </client>
                          </clients>
                        </data>";

      XDocument xDoc = XDocument.Parse(xmlData);

      List<string> results = xDoc.Descendants("data")
                            .Descendants("client")
                            .Select(x => x.Element("clientName").Value)
                            .ToList<string>();

    }
  }
}

UPDATE: I confirmed that the following assemblies were in the GAC. System.Xml and System.Xml.Linq. I also added the compiler version to the constructor and I still get the same error.

  CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
3
  • Extension methods were added in c# 3.5. What happens if you explicitly target a compiler version later than that? See What happens if I don't specify CompilerVersion with CSharpCodeProvider and why do most samples specify it? and How can I target a specific language version using CodeDOM?. Commented Feb 16, 2018 at 19:41
  • I am not sure what happens as I am not specifying the target framework (perhaps that is the issue?). I will try and add this and also change the machine.config and web.config. Thank you for the links! Commented Feb 16, 2018 at 20:10
  • I ran a script that contained Environment.Version and I got back 4.0.30319.34209. I was hoping this might be the answer, but I guess not. From what I have looked up this means the environment is .NET v4.5.2 Commented Feb 16, 2018 at 22:30

1 Answer 1

4

After searching for related errors I found the solution. I needed to add System.Core as a referenced assembly.

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

Once I did this then the LINQ assemblies were used and I was able to use LINQ extensions. So to be clear my new code is

CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.ReferencedAssemblies.Add("System.Core.dll");

I am not sure why the reference to System.Core.dll is needed to be added as I would assume that it was referenced by default when creating a compiler instance but I guess not.

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.