简体   繁体   English

.Net Core-CS0012'对象'在未引用的程序集中定义

[英].Net Core - CS0012 'Object' is defined in an assembly that is not referenced

I'm brand new to .Net Core and I'm trying to build a build system based on it. 我是.Net Core的新手,我正在尝试基于它构建构建系统。 As part of this project, I've created an abstract class that spells out what a build task should implement, and I've stuffed this into a shared library. 作为该项目的一部分,我创建了一个抽象类,该抽象类阐明了构建任务应实现的内容,并将其填充到共享库中。

The executable project references this library and scans project directories for a specially named directory, then checks to see if there are any .cs files in there. 可执行项目引用此库,并在项目目录中扫描特别命名的目录,然后检查其中是否存在任何.cs文件。 These scripts are loaded and then compilation is attempted using the tools provided through Microsoft.CodeAnalysis and friends. 加载这些脚本,然后使用Microsoft.CodeAnalysis和朋友提供的工具尝试编译。

With that background, here's an odd issue I'm hitting at the compilation stage: 在这种背景下,我在编译阶段遇到了一个奇怪的问题:

If I attempt to supply the shared library containing the abstract class to the compilation process as a reference, I get the following error: 如果我尝试将包含抽象类的共享库提供给编译过程作为参考,则会出现以下错误:

Failed CS0012: The type 'Object' is defined in an assembly that is not referenced. 失败的CS0012:类型'对象'在未引用的程序集中定义。 You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. 您必须添加对程序集'mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e'的引用。

Followed by a bunch complaints about predefined types: 其次是关于预定义类型的抱怨:

CS0518: Predefined type 'System.Boolean' is not defined or imported CS0518: Predefined type 'System.Boolean' is not defined or imported CS0518: Predefined type 'System.Void' is not defined or imported ... etc etc. CS0518:未定义或导入预定义类型'System.Boolean'CS0518:未定义或导入预定义类型'System.Boolean'CS0518:未定义或导入预定义类型'System.Void'等等。

However, if I omit the reference and instead parse each of the shared library's source files into syntax trees and pass them to the compilation process, the whole process succeeds and I get a returned in-memory assembly I can pull types out of and instantiate. 但是,如果我省略了引用,而是将每个共享库的源文件解析为语法树,然后将它们传递给编译过程,则整个过程将成功,并且我将获得一个返回的内存中程序集,可以将类型拉出并实例化。

I've read everything on this error that Google has to offer, and I'm at a loss. 我已经阅读了有关Google必须提供的该错误的所有内容,但我很茫然。 Can somebody enlighten me as to why this is happening and bonus internet points for how I can accomplish my original goal of simply linking in a common shared library? 有人能启发我为什么会这样,并为我如何实现简单地链接到公共共享库中的最初目标提供额外的互联网积分吗?

Relevant code 相关代码

    CSharpParseOptions parseOptions = CSharpParseOptions.Default;

    SyntaxTree jobSyntaxTree = CSharpSyntaxTree.ParseText(scriptContents, parseOptions);

    string generatedAssemblyName = Path.GetRandomFileName();
    var referencedAssemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies();

    foreach(var referencedAssembly in referencedAssemblies)
    {
        var rfas = Assembly.Load(referencedAssembly);
        references.Add(MetadataReference.CreateFromFile(rfas.Location)); 
    }

    var op = new  CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

    CSharpCompilation compilation = CSharpCompilation.Create(
       generatedAssemblyName,
       syntaxTrees: new[] { jobSyntaxTree },
       references: references,
       options: op);

    var ms = new MemoryStream();

    EmitOptions emitOptions = new EmitOptions();

    EmitResult result = compilation.Emit(ms);

    if(result.Success)
    {
       // Yay
    }
    else
    {
       // Boo-hoo
    }

Project.json file for the shared library 共享库的Project.json文件

{
    "title": "BuildBotCore",
    "version": "1.0.0-*",
    "buildOptions": {
        "emitEntryPoint": false,
        "preserveCompilationContext": true
    },
    "dependencies": {
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.0"
        },
        "System.Runtime": "4.1.0",
        "System.Runtime.Loader": "4.0.0",
        "Microsoft.NETCore.Portable.Compatibility": "1.0.1"
    },
    "frameworks": {
        "netcoreapp1.0": {
            "imports": "netcore50",
            "buildOptions": {
                "preserveCompilationContext": true
            }
        }
    },
    "configurations": {
        "Debug": {
            "buildOptions": {
                "define": [
                    "DEBUG",
                    "TRACE"
                ],
                "optimize": false,
                "preserveCompilationContext": true
            }
        },
        "Release": {
            "buildOptions": {
                "define": [
                    "RELEASE",
                    "TRACE"
                ],
                "optimize": true,
                "preserveCompilationContext": true
            }
        }
    }
}

Project.json for main executable 主可执行文件的Project.json

{
    "version": "1.0.0-*",
    "buildOptions": {
        "emitEntryPoint": true,
        "preserveCompilationContext": true
    },
    "dependencies": {
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.0"
        },
        "System.Runtime": "4.1.0",
        "Microsoft.CodeAnalysis.CSharp": "1.3.2",
        "System.Runtime.Loader": "4.0.0",
        "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
        "BuildBotCore": "1.0.0-*"
    },
    "frameworks": {
        "netcoreapp1.0": {
            "imports": "netcore50",
            "buildOptions": {
                "preserveCompilationContext": true
            }
        }
    },
    "configurations": {
        "Debug": {
            "buildOptions": {
                "define": [
                    "DEBUG",
                    "TRACE"
                ],
                "optimize": false,
                "preserveCompilationContext": true
            }
        },
        "Release": {
            "buildOptions": {
                "define": [
                    "RELEASE",
                    "TRACE"
                ],
                "optimize": true,
                "preserveCompilationContext": true
            }
        }
    }
}

TL;DR TL; DR
At the end of the day you need to pass a reference to "mscorlib.dll" and its private variant. 最终,您需要传递对“ mscorlib.dll”及其私有变体的引用。 This will make the above compilation errors go away. 这将使上述编译错误消失。 This is also cross-platform in .net core, as I've tested this solution on Linux and Windows. 这也是.net核心中的跨平台,因为我已经在Linux和Windows上测试了该解决方案。

Full version & code samples 完整版本和代码示例
Since I'm waiting for account deletion, I'll post this last answer. 由于我正在等待帐户删除,因此我将发布最后一个答案。

The solution is to manually include mscorlib.dll based on the location of some other type's assembly. 解决方案是根据其他类型的程序集的位置手动包括mscorlib.dll。 Like this: 像这样:

// Get the directory of a core assembly. We need this directory to
// build out our platform specific reference to mscorlib. mscorlib
// and the private mscorlib must be supplied as references for
// compilation to succeed. Of these two assemblies, only the private
// mscorlib is discovered via enumerataing assemblies referenced by
// this executing binary.
var dd = typeof(Enumerable).GetTypeInfo().Assembly.Location;
var coreDir = Directory.GetParent(dd);            

List<MetadataReference> references = new List<MetadataReference>
{   
    // Here we get the path to the mscorlib and private mscorlib
    // libraries that are required for compilation to succeed.
    MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
    MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)           
};

There is a second mscorelib, but its name is prefixed with "private". 还有第二个mscorelib,但其名称前缀为“ private”。 This is automatically referenced by the executing assembly, so there's no need to manually generate its path like above. 这由执行程序集自动引用,因此不需要像上面一样手动生成其路径。

You get this private mscorlib when you pull references from the executing assembly which is doing the dynamic code compilation itself. 当您从正在执行动态代码编译本身的执行程序集中提取引用时,会获得此私有mscorlib。 Like so: 像这样:

// Enumerate all assemblies referenced by this executing assembly
// and provide them as references to the build script we're about to
// compile.
var referencedAssemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies();
foreach(var referencedAssembly in referencedAssemblies)
{
    var loadedAssembly = Assembly.Load(referencedAssembly);   

    references.Add(MetadataReference.CreateFromFile(loadedAssembly.Location)); 
}

So now with these references assembled, you can simply pass them to your code compilation: 因此,现在将这些引用组装在一起,您只需将它们传递给代码编译即可:

// Initialize the compilation with our options, references and the
// already parsed syntax tree of the build script.
CSharpCompilation compilation = CSharpCompilation.Create(
    generatedAssemblyName,
    syntaxTrees: new[] { jobSyntaxTree },
    references: references,
    options: op);           

// Compile and emit new assembly into memory.
var ms = new MemoryStream();
EmitResult result = compilation.Emit(ms);

... and voila, you can dynamically compile in-code with Roslyn cross-platform in .Net core. ...,瞧,您可以使用.Net core中的Roslyn跨平台动态地编译代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 CS0012 类型“EventLogEntryType”在未引用的程序集中定义 - CS0012 The type 'EventLogEntryType' is defined in an assembly that is not referenced 错误CS0012:类型“DbConnection”在未引用的程序集中定义 - Error CS0012: The type 'DbConnection' is defined in an assembly that is not referenced CS0012 C#类型“ HttpContext”在未引用的程序集中定义 - CS0012 C# The type 'HttpContext' is defined in an assembly that is not referenced 错误CS0012:类型'TaskAwaiter <>'在未引用的程序集中定义 - error CS0012: The type 'TaskAwaiter<>' is defined in an assembly that is not referenced CS0012 System.enum在未针对.NET 4.5的构建服务器上引用的程序集中定义 - CS0012 System.enum is defined in an assembly not referenced on build server targeting .NET 4.5 错误CS0012:类型&#39;ConnectionStringSettings&#39;在升级到Visual Studio 2015后未引用的程序集中定义 - error CS0012: The type 'ConnectionStringSettings' is defined in an assembly that is not referenced after upgrading to Visual Studio 2015 使用RazorTemplates库时发生错误:&#39;CS0012:类型&#39;System.Attribute&#39;在未引用的程序集中定义&#39; - Error when using RazorTemplates library: 'CS0012: The type 'System.Attribute' is defined in an assembly that is not referenced' MSBuild错误CS0012 - MSBuild Error CS0012 FluentAssertions 错误 CS0012:您必须添加对程序集 System.Data 的引用 - FluentAssertions error CS0012: You must add a reference to assembly System.Data .net Core amd Roslyn CSharpCompilation,类型'Object'在未引用的程序集中定义 - .net Core amd Roslyn CSharpCompilation, The type 'Object' is defined in an assembly that is not referenced
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM