C# 在CSharpCompilation.net Core中未获取命名空间/引用

C# 在CSharpCompilation.net Core中未获取命名空间/引用,c#,.net-core,roslyn,roslyn-code-analysis,C#,.net Core,Roslyn,Roslyn Code Analysis,我有一个使用一些动态编译代码的项目,我正在从.net framework升级到.net core 3.1 我无法获取包含newtonsoft.json.dll的简单测试用例,并获取错误“找不到类型或命名空间名称'newtonsoft'。我在第一次尝试添加库时遇到类似问题,但通过使用当前加载的程序集()。使用“Core“我没有得到关于库的错误,但它不知道类型,就像它没有被加载一样 我尝试了使用项目库(注释掉)和直接指定它们,但都有相同的问题。要重新创建,请创建一个名为“TestScript”的新.

我有一个使用一些动态编译代码的项目,我正在从.net framework升级到.net core 3.1

我无法获取包含newtonsoft.json.dll的简单测试用例,并获取错误“找不到类型或命名空间名称'newtonsoft'。我在第一次尝试添加库时遇到类似问题,但通过使用当前加载的程序集()。使用“Core“我没有得到关于库的错误,但它不知道类型,就像它没有被加载一样

我尝试了使用项目库(注释掉)和直接指定它们,但都有相同的问题。要重新创建,请创建一个名为“TestScript”的新.netCore 3.1控制台应用程序,并安装nuget软件包“Microsoft.CodeAnalysis.CSharp.Scripting”v3.7.0,“Newtonsoft.Json”v12.0.3,然后使用以下代码

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Diagnostics;
using Newtonsoft.Json.Linq;

namespace TestScript
{  
  class Program
  {
    public static void Example1()
    {
      var assemblyName = "UserScript";
      var code = @"namespace UserScript
                { 
                  using System;
                  using System.IO;
                  using System.Collections.Generic;
                  using Newtonsoft.Json.Linq;
                  public class RunScript
                  {
                    private const int x = 99;
                    public int Eval()
                    {
                      JObject j = new JObject();
                      return x; 
                    }
                  }
                }";

      SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
      var references = new List<MetadataReference>();
      //Load project libraries
      //var assemblies = AppDomain.CurrentDomain
      //                .GetAssemblies()
      //                .Where(a => !a.IsDynamic)
      //                .Select(a => a.Location);
      //foreach (var item in assemblies)
      //{
      //  if (!item.Contains("xunit"))
      //    references.Add(MetadataReference.CreateFromFile(item));
      //}

      //or specify the libraries to load.

      var coreDir = Directory.GetParent(typeof(Enumerable).GetTypeInfo().Assembly.Location);
      var exeDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
      references.Add(MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location));
      references.Add(MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location));
      references.Add(MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"));
      references.Add(MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Runtime.dll"));
      if (File.Exists(exeDir + "\\Newtonsoft.Json.dll"))
        references.Add(MetadataReference.CreateFromFile(exeDir + "\\Newtonsoft.Json.dll"));
      else
        throw new Exception("Missing newtonsoft DLL");


      CSharpCompilation compilation = CSharpCompilation.Create(
          assemblyName,
          new[] { syntaxTree },
          new MetadataReference[]
          {
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
          },
          new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

      using (var memoryStream = new MemoryStream())
      {
        var result = compilation.Emit(memoryStream);

        if (result.Success)
        {
          memoryStream.Seek(0, SeekOrigin.Begin);
          Assembly assembly = Assembly.Load(memoryStream.ToArray());

          Type testClassType = assembly.GetType("TestNamespace.TestClass");
          var addResult = (int)testClassType.GetMethod("Add").Invoke(null, new object[] { 3, 4 });
          Console.WriteLine(addResult);
        }
        else
        {
          Console.WriteLine("Failed to compile");
          for (var i = 0; i < result.Diagnostics.Length; i++)
          {
            Console.WriteLine(result.Diagnostics[i].ToString());
          }
        }
      }
    }
    static void Main(string[] args)
    {
      JObject j = null; //to make sure newtonsoft is included if loading current projects libraries

      Example1();
    }
  }
}
使用系统;
使用System.IO;
使用System.Linq;
使用System.Collections.Generic;
运用系统反思;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.CSharp;
使用系统诊断;
使用Newtonsoft.Json.Linq;
命名空间测试脚本
{  
班级计划
{
公共静态无效示例1()
{
var assemblyName=“UserScript”;
var code=@“命名空间用户脚本
{ 
使用制度;
使用System.IO;
使用System.Collections.Generic;
使用Newtonsoft.Json.Linq;
公共类运行脚本
{
私有常量int x=99;
公共内部评估()
{
JObject j=新的JObject();
返回x;
}
}
}";
SyntaxTree SyntaxTree=CSharpSyntaxTree.ParseText(代码);
var references=新列表();
//加载项目库
//var assemblies=AppDomain.CurrentDomain
//.getAssemblys()
//.其中(a=>!a.IsDynamic)
//.选择(a=>a.位置);
//foreach(程序集中的变量项)
//{
//如果(!item.Contains(“xunit”))
//添加(MetadataReference.CreateFromFile(项));
//}
//或者指定要加载的库。
var coreDir=Directory.GetParent(typeof(可枚举).GetTypeInfo().Assembly.Location);
var exeDir=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
Add(MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location));
Add(MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location));
添加(MetadataReference.CreateFromFile(coreDir.FullName+Path.directoryseportorchar+mscorlib.dll));
添加(MetadataReference.CreateFromFile(coreDir.FullName+Path.directoryseportorchar+“System.Runtime.dll”);
if(File.Exists(exeDir+“\\Newtonsoft.Json.dll”))
添加(MetadataReference.CreateFromFile(exeDir+“\\Newtonsoft.Json.dll”);
其他的
抛出新异常(“缺少newtonsoft DLL”);
csharpcomilation=csharpcomilation.Create(
汇编名,
新[]{syntaxTree},
新MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object.Assembly.Location)
},
新的CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
使用(var memoryStream=new memoryStream())
{
var result=compilation.Emit(memoryStream);
如果(结果、成功)
{
memoryStream.Seek(0,SeekOrigin.Begin);
Assembly=Assembly.Load(memoryStream.ToArray());
类型testClassType=assembly.GetType(“TestNamespace.TestClass”);
var addResult=(int)testClassType.GetMethod(“Add”).Invoke(null,新对象[]{3,4});
Console.WriteLine(addResult);
}
其他的
{
Console.WriteLine(“编译失败”);
对于(变量i=0;i
如果您没有忘记使用您建立的
参考
列表,那么您的代码应该可以正常工作

请参阅.NETFiddle()上的测试代码-我在那里使用了
AppDomain
方法(您注释掉的方法)

编辑:以下是完整的工作代码,以防小提琴被删除:

public static void Main(string[] args)
{
    var j = new JObject(); // ensure assembly is available
    Example1();
}

public static void Example1()
{
    var assemblyName = "UserScript";
    var code = @"namespace UserScript { 
                  using Newtonsoft.Json;
                  public class RunScript {
                   public static string Eval() {
                    return JsonConvert.SerializeObject(new int[] {1,2,3,4});
                   }
                  }
                }";

    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
    
    //Load project libraries
    var references = AppDomain.CurrentDomain
        .GetAssemblies()
        .Where(a => !a.IsDynamic)
        .Select(a => a.Location)
        .Where(s => !string.IsNullOrEmpty(s))
        .Where(s => !s.Contains("xunit"))
        .Select(s => MetadataReference.CreateFromFile(s))
        .ToList()
        ;

    CSharpCompilation compilation = CSharpCompilation.Create(
        assemblyName,
        new[] { syntaxTree },
        references, //<-- you're missing this
        new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

    using (var memoryStream = new MemoryStream())
    {
        var result = compilation.Emit(memoryStream);

        if (result.Success)
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            Assembly assembly = Assembly.Load(memoryStream.ToArray());

            var testClassType = assembly.GetType("UserScript.RunScript");
            var invokeResult = (string)testClassType.GetMethod("Eval").Invoke(null, null);
            Console.WriteLine(invokeResult);
        }
        else
        {
            Console.WriteLine("Failed to compile");
            foreach (var diag in result.Diagnostics)
                Console.WriteLine(diag);
        }
    }
}
publicstaticvoidmain(字符串[]args)
{
var j=new JObject();//确保程序集可用
例1();
}
公共静态无效示例1()
{
var assemblyName=“UserScript”;
var code=@“命名空间用户脚本{
使用Newtonsoft.Json;
公共类运行脚本{
公共静态字符串Eval(){
返回JsonConvert.SerializeObject(新的int[]{1,2,3,4});
}
}
}";
SyntaxTree SyntaxTree=CSharpSyntaxTree.ParseText(代码);
//加载项目库
var references=AppDomain.CurrentDomain
.getAssemblys()
.其中(a=>!a.IsDynamic)
.选择(a=>a.位置)
.Where(s=>!string.IsNullOrEmpty(s))
。其中(s=>!s.Contains(“xunit”))
.Select(s=>MetadataReference.CreateFromFile)
托利斯先生()
;
csharpcomilation=csharpcomilation.Create(
汇编名,
新[]{syntaxTree},

引用,//如果您没有忘记使用您建立的
引用列表,那么您的代码应该可以正常工作

请参阅.NETFiddle()上的测试代码-我在那里使用了
AppDomain
方法(您注释掉的方法)

编辑:这里
// Non-existent Type and Method...
Type testClassType = assembly.GetType("TestNamespace.TestClass");
var addResult = (int)testClassType.GetMethod("Add").Invoke(null, new object[] { 3, 4 });
public static void Main(string[] args)
{
    var j = new JObject(); // ensure assembly is available
    Example1();
}

public static void Example1()
{
    var assemblyName = "UserScript";
    var code = @"namespace UserScript { 
                  using Newtonsoft.Json;
                  public class RunScript {
                   public static string Eval() {
                    return JsonConvert.SerializeObject(new int[] {1,2,3,4});
                   }
                  }
                }";

    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
    
    //Load project libraries
    var references = AppDomain.CurrentDomain
        .GetAssemblies()
        .Where(a => !a.IsDynamic)
        .Select(a => a.Location)
        .Where(s => !string.IsNullOrEmpty(s))
        .Where(s => !s.Contains("xunit"))
        .Select(s => MetadataReference.CreateFromFile(s))
        .ToList()
        ;

    CSharpCompilation compilation = CSharpCompilation.Create(
        assemblyName,
        new[] { syntaxTree },
        references, //<-- you're missing this
        new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

    using (var memoryStream = new MemoryStream())
    {
        var result = compilation.Emit(memoryStream);

        if (result.Success)
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            Assembly assembly = Assembly.Load(memoryStream.ToArray());

            var testClassType = assembly.GetType("UserScript.RunScript");
            var invokeResult = (string)testClassType.GetMethod("Eval").Invoke(null, null);
            Console.WriteLine(invokeResult);
        }
        else
        {
            Console.WriteLine("Failed to compile");
            foreach (var diag in result.Diagnostics)
                Console.WriteLine(diag);
        }
    }
}