【问题标题】:Receiving "You must add a reference to assembly 'netstandard'" Errors during Runtime Compilation在运行时编译期间收到“您必须添加对程序集 'netstandard' 的引用”错误
【发布时间】:2020-06-05 19:47:27
【问题描述】:

使用 C# 运行时编译 (Roslyn),我收到许多错误,指出我没有添加对 netstandard 的引用,尽管在 netcoreapp。

错误以下列格式显示:

类型“XXX”在未引用的程序集中定义。 您必须添加对程序集 'netstandard, Version=2.0.0.0...

的引用

由此产生的代码处理可以提炼成以下sn-p:

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace Compiler
{
    public static class Compiler
    {
        public static Assembly CompileAssembly(string code, bool compileAsExecutable = false)
        {
            var outputKind = compileAsExecutable ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary;
            var syntaxTree = CSharpSyntaxTree.ParseText(code);
            var syntaxTrees = new[] {syntaxTree};
            var systemAssemblyReference = GetMetadataReference<object>();
            var patchBandAssemblyReference = GetMetadataReference<AssemblyTargetedPatchBandAttribute>();
            var references = new[] {systemAssemblyReference, patchBandAssemblyReference};
            var cSharpCompilationOptions = new CSharpCompilationOptions(outputKind);
            var compilation = CSharpCompilation.Create(@"Countdown", syntaxTrees, references, cSharpCompilationOptions);

            using (var assemblyStream = new MemoryStream())
            {
                var emitResult = compilation.Emit(assemblyStream);

                if (emitResult.Success)
                {
                    var assemblyBytes = assemblyStream.ToArray();

                    return Assembly.Load(assemblyBytes);
                }

                var errors = emitResult
                    .Diagnostics
                    .Select(diagnostic => diagnostic.GetMessage())
                    .Select(message => new Exception(message));

                throw new AggregateException(errors);
            }
        }

        private static string GetAssemblyLocation<T>()
        {
            var typeOfT = typeof(T);

            return typeOfT.Assembly.Location;
        }

        private static PortableExecutableReference GetMetadataReference<T>()
        {
            var assemblyLocation = GetAssemblyLocation<T>();

            return MetadataReference.CreateFromFile(assemblyLocation);
        }
    }
}

【问题讨论】:

    标签: c# .net-core compiler-errors compilation roslyn


    【解决方案1】:

    解决方案是添加对 netstandard.dll 的引用:

    using System;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime;
    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp;
    
    namespace Compiler
    {
        public static class Compiler
        {
            public static Assembly CompileAssembly(string code, bool compileAsExecutable = false)
            {
                var outputKind = compileAsExecutable ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary;
                var syntaxTree = CSharpSyntaxTree.ParseText(code);
                var syntaxTrees = new[] {syntaxTree};
    
                // Requested the reference be fetched
                var runtimeSpecificReference = GetRuntimeSpecificReference();
                var systemAssemblyReference = GetMetadataReference<object>();
                var patchBandAssemblyReference = GetMetadataReference<AssemblyTargetedPatchBandAttribute>();
    
                // Added the reference to the value here
                var references = new[] {runtimeSpecificReference, systemAssemblyReference, patchBandAssemblyReference};
    
                var cSharpCompilationOptions = new CSharpCompilationOptions(outputKind);
                var compilation = CSharpCompilation.Create(@"Countdown", syntaxTrees, references, cSharpCompilationOptions);
    
                using (var assemblyStream = new MemoryStream())
                {
                    var emitResult = compilation.Emit(assemblyStream);
    
                    if (emitResult.Success)
                    {
                        var assemblyBytes = assemblyStream.ToArray();
    
                        return Assembly.Load(assemblyBytes);
                    }
    
                    var errors = emitResult
                        .Diagnostics
                        .Select(diagnostic => diagnostic.GetMessage())
                        .Select(message => new Exception(message));
    
                    throw new AggregateException(errors);
                }
            }
    
            private static string GetAssemblyLocation<T>()
            {
                var typeOfT = typeof(T);
    
                return typeOfT.Assembly.Location;
            }
    
            private static PortableExecutableReference GetMetadataReference<T>()
            {
                var assemblyLocation = GetAssemblyLocation<T>();
    
                return MetadataReference.CreateFromFile(assemblyLocation);
            }
    
            // This function was needed
            private static PortableExecutableReference GetRuntimeSpecificReference()
            {
                var assemblyLocation = GetAssemblyLocation<object>();
                var runtimeDirectory = Path.GetDirectoryName(assemblyLocation);
                var libraryPath = Path.Join(runtimeDirectory, @"netstandard.dll");
    
                return MetadataReference.CreateFromFile(libraryPath);
            }
        }
    }
    

    【讨论】:

    • SO 用户必须深入挖掘才能找到您“隐藏”该问题的解决方案的位置。如果您清楚地表明您所做的更改以使您的代码正常工作,那么您的解决方案可能会更有帮助
    • 我添加了代码 cmets 来指示更改。对进一步突出代码 sn-p 中的增量有何建议?
    猜你喜欢
    • 1970-01-01
    • 2018-09-30
    • 2022-09-29
    • 1970-01-01
    • 2011-10-29
    • 2022-06-11
    • 1970-01-01
    • 2019-06-28
    • 2019-10-16
    相关资源
    最近更新 更多