【问题标题】:C# scripting API does not load assemblyC# 脚本 API 不加载程序集
【发布时间】:2017-05-11 10:46:00
【问题描述】:

我尝试编写一个 .net 核心控制台程序来使用 C# 脚本 API 来运行 linq 语句,但我一直收到错误提示

'System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ---> System.IO.FileLoadException: Native image 无法多次加载。

这是我的程序:

using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                var scriptOptions = ScriptOptions.Default;

                //Add reference to mscorlib
                var mscorlib = typeof(System.Object).GetTypeInfo().Assembly;
                var systemCore = typeof(System.Linq.Enumerable).GetTypeInfo().Assembly;
                scriptOptions = scriptOptions.AddReferences(mscorlib, systemCore);

                //Add namespaces
                scriptOptions = scriptOptions.AddImports("System");
                scriptOptions = scriptOptions.AddImports("System.Linq");
                scriptOptions = scriptOptions.AddImports("System.Collections.Generic");

                var state = CSharpScript.RunAsync(@"var x = new List<int>(){1,2,3,4,5};", scriptOptions).Result;
                state = state.ContinueWithAsync("var y = x.Take(3).ToList();").Result;

                var y = state.Variables[1];
                var yList = (List<int>)y.Value;
                foreach(var val in yList)
                {
                Console.Write(val + " "); // Prints 1 2 3
                }
            }
            catch (CompilationErrorException e)
            {
                Console.WriteLine(string.Join(Environment.NewLine, e.Diagnostics));
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Join(Environment.NewLine, e));
            }
        }
    }
}

这是我的 project.json:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {
    "Microsoft.CodeAnalysis.CSharp.Scripting": "2.0.0-rc2"
  },
  "frameworks": {
    "netcoreapp1.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      },
      "imports": ["dnxcore50", "net452"]
    }
  }
}

【问题讨论】:

    标签: c# scripting


    【解决方案1】:

    似乎是 Microsoft.CodeAnalysis.ScriptingMicrosoft.NETCore.App 针对不同版本的 System dll 之间的依赖冲突,直到它们对齐,看起来你可以使用 InteractiveAssemblyLoader 告诉 CSharpScript 编译器加载应用实际提供的依赖版本。

        var scriptOptions = ScriptOptions.Default;
    
        // Add reference to mscorlib
        var mscorlib = typeof(object).GetTypeInfo().Assembly;
        var systemCore = typeof(System.Linq.Enumerable).GetTypeInfo().Assembly;
    
        var references = new[] { mscorlib, systemCore };
        scriptOptions = scriptOptions.AddReferences(references);
    
        List<int> yList;
        using (var interactiveLoader = new InteractiveAssemblyLoader())
        {
            foreach (var reference in references)
            {
                interactiveLoader.RegisterDependency(reference);
            }
    
            // Add namespaces
            scriptOptions = scriptOptions.AddImports("System");
            scriptOptions = scriptOptions.AddImports("System.Linq");
            scriptOptions = scriptOptions.AddImports("System.Collections.Generic");
    
            // Initialize script with custom interactive assembly loader
            var script = CSharpScript.Create(@"", scriptOptions, null, interactiveLoader);
            var state = script.RunAsync().Result;
    
            state = state.ContinueWithAsync(@"var x = new List<int>(){1,2,3,4,5};").Result;
            state = state.ContinueWithAsync("var y = x.Take(3).ToList();").Result;
    
            var y = state.Variables[1];
            yList = (List<int>)y.Value;
        }
    
        foreach (var val in yList)
        {
            Console.Write(val + " "); // Prints 1 2 3
        }
    
        // ...
    

    【讨论】:

    • 哇,好用~非常感谢。 p.s. InteractiveAssemblyLoader 是一次性的,因此您可能希望使用 using 更新此答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2016-10-24
    • 1970-01-01
    相关资源
    最近更新 更多