【问题标题】:Roslyn has no reference to System.RuntimeRoslyn 没有参考 System.Runtime
【发布时间】:2014-05-28 09:08:58
【问题描述】:

我正在做一个项目,我们正在使用 Roslyn 为我们编译一些模板。 现在,当我编译模板时,我在CompileResult.Diagnostics 中收到多个错误。

错误是:

(21,6): error CS0012: The type 'System.Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
(21,6): error CS0012: The type 'System.Type' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

看到这些错误,我以为我没有正确添加对System.Runtime 程序集的引用。但是,在检查加载的程序集之后,这似乎是有序的。

private IEnumerable<MetadataReference> GetGlobalReferences()
{
    var assemblies = new [] 
        {
            typeof(System.Object).Assembly,                         //mscorlib
            typeof(System.Composition.ExportAttribute).Assembly,    //System.Composition (MEF)
            typeof(System.CodeDom.Compiler.CodeCompiler).Assembly,  //System.CodeDom.Compiler
        };

    var refs = from a in assemblies
                select new MetadataFileReference(a.Location);

    return refs.ToList();
}

还有编译本身:

public void Compile(AssemblyFileInfo assemblyInfo)
{
    Parse(assemblyInfo.Files);

    var compilation = CSharpCompilation.Create(assemblyInfo.FilePath, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                        .AddReferences(GetGlobalReferences())
                        .AddSyntaxTrees(assemblyInfo.SourceCodeSyntaxTrees);

    assemblyInfo.CompileResult = compilation.Emit(assemblyInfo.FilePath);
}

我是否遗漏了一些明显的东西?看起来成功编译的所有先决条件都已满足,但显然它们并未满足。

作为参考,这是我正在尝试编译的(混淆的)代码:

namespace Project.Rules.Generated
{
    using System;
    using System.Runtime;
    using System.Composition;
    using System.CodeDom.Compiler;

    [Export(typeof(IProject))]
    [GeneratedCode("Project Template Compiler", "1.0")]
    public sealed class ProcessPriorityValue : ProjectConcreteClass
    {
        public override void Execute(ProjectExecutionContext ctx)
        {
            CurrentContext = ctx;
        }
    }
}

编辑 我的搜索有点进步了。错误消息中指定的 PublicKeyToken 与 System.Composition 程序集的 PublicKeyToken 匹配。我的猜测是添加所有程序集可能会解决问题。 这是正确的,或者至少是解决方案的一部分。 通过使用 dotPeek,我能够检查不同程序集中存在哪些对象。 有了这些知识,我将 GetGlobalReferences() 方法更改为:

private IEnumerable<MetadataReference> GetGlobalReferences()
{
    var assemblies = new [] 
        {
            typeof(System.Object).Assembly,                                     //mscorlib
            typeof(System.Composition.ExportAttribute).Assembly,                //System.Composition.AttributeModel
            typeof(System.Composition.Convention.ConventionBuilder).Assembly,   //System.Composition.Convention
            typeof(System.Composition.Hosting.CompositionHost).Assembly,        //System.Composition.Hosting
            typeof(System.Composition.CompositionContext).Assembly,             //System.Composition.Runtime
            typeof(System.Composition.CompositionContextExtensions).Assembly,   //System.Composition.TypedParts
            typeof(System.CodeDom.Compiler.CodeCompiler).Assembly,              //System.CodeDom.Compiler
        };

    var refs = from a in assemblies
                select new MetadataFileReference(a.Location);

    return refs.ToList();
}

如您所见,我现在通过指定程序集中存在的对象来添加所有 System.Composition 程序集。 通过添加System.Composition.Runtime,我的编译错误得到了解决。

但这确实引入了一个不同的错误。您可以自己查看,System.Composition.Runtime 中有一个通用的 Export 类: public sealed class Export&lt;T&gt; : IDisposable 因此,我现在收到此错误:

(21,6): error CS0404: Cannot apply attribute class 'System.Composition.Export<T>' because it is generic

由于某种原因,代码现在想要使用 System.Composition.Runtime.Export&lt;T&gt; 而不是在 System.Composition.AttributeModel 程序集中定义的 ExportAttribute。

edit2

我可以确认上面的代码使用了System.Composition.Export&lt;T&gt; 而不是ExportAttribute。我通过将[Export(typeof(IProject)] 更改为[ExportAttribute(typeof(IProject)] 发现了这一点。由于此更改,返回了原始错误。 看起来程序集 System.Composition.AttributeModel 没有正确加载/引用,但在检查 compilation 后,我可以看到程序集被引用了。

我目前得到的引用程序集是:

+       [0] mscorlib, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000  Microsoft.CodeAnalysis.AssemblyIdentity
+       [1] System.Composition.AttributedModel, Version=1.0.20.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293   Microsoft.CodeAnalysis.AssemblyIdentity
+       [2] System.Composition.Convention, Version=1.0.20.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293    Microsoft.CodeAnalysis.AssemblyIdentity
+       [3] System.Composition.Hosting, Version=1.0.20.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293   Microsoft.CodeAnalysis.AssemblyIdentity
+       [4] System.Composition.Runtime, Version=1.0.20.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293   Microsoft.CodeAnalysis.AssemblyIdentity
+       [5] System.Composition.TypedParts, Version=1.0.20.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293    Microsoft.CodeAnalysis.AssemblyIdentity
+       [6] Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293  Microsoft.CodeAnalysis.AssemblyIdentity
+       [7] System, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000    Microsoft.CodeAnalysis.AssemblyIdentity
+       [8] System.Core, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000   Microsoft.CodeAnalysis.AssemblyIdentity
+       [9] System.Data, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000   Microsoft.CodeAnalysis.AssemblyIdentity

【问题讨论】:

  • 您的 cmets 可能具有误导性。据我所知,System.Runtime.ProfileOptimizationmscorlib 中,而不是在System.Runtime 程序集中。
  • 你说得对,我自己也是这么想的。似乎没有System.Runtime 程序集,所有东西都应该在mcorslib 中可用。刚刚从帖子和来源中删除了该行,所以它有点干净。
  • 这听起来像是在为 csc 使用 /nostdlib 选项时。
  • 您的回答有助于解决我的问题。谢谢!您不想将其作为真实答案发布,而不是作为问题的一部分发布吗?我几乎忽略了它... P.S.恭喜你获得 2226 SO 积分 ;)
  • 好点!我将其作为单独的答案发布。

标签: c# roslyn


【解决方案1】:

应 Dejan 在评论部分的要求,我会将答案(对我的问题)作为真实答案发布。


我发现了问题所在!编译器一直都是正确的。 smack0007blog post 触发了我尝试别的东西。尝试手动引用必要的 dll,而不是使用 Facade dll。 GetGlobalReferences 方法现在看起来像这样:

private IEnumerable<MetadataReference> GetGlobalReferences()
{
    var assemblies = new [] 
        {
            /*Making sure all MEF assemblies are loaded*/
            typeof(System.Composition.Convention.AttributedModelProvider).Assembly, //System.Composition.AttributeModel
            typeof(System.Composition.Convention.ConventionBuilder).Assembly,   //System.Composition.Convention
            typeof(System.Composition.Hosting.CompositionHost).Assembly,        //System.Composition.Hosting
            typeof(System.Composition.CompositionContext).Assembly,             //System.Composition.Runtime
            typeof(System.Composition.CompositionContextExtensions).Assembly,   //System.Composition.TypedParts

            /*Used for the GeneratedCode attribute*/
            typeof(System.CodeDom.Compiler.CodeCompiler).Assembly,              //System.CodeDom.Compiler
        };

    var refs = from a in assemblies 
                select new MetadataFileReference(a.Location);
    var returnList = refs.ToList();

    //The location of the .NET assemblies
    var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);

    /* 
        * Adding some necessary .NET assemblies
        * These assemblies couldn't be loaded correctly via the same construction as above,
        * in specific the System.Runtime.
        */
    returnList.Add(new MetadataFileReference(Path.Combine(assemblyPath, "mscorlib.dll")));
    returnList.Add(new MetadataFileReference(Path.Combine(assemblyPath, "System.dll")));
    returnList.Add(new MetadataFileReference(Path.Combine(assemblyPath, "System.Core.dll")));
    returnList.Add(new MetadataFileReference(Path.Combine(assemblyPath, "System.Runtime.dll")));

    return returnList;
}

在反编译System.Runtime.dll 时,我也看到了为什么不能以任何其他方式引用它。 dll 是空的,它只包含对其他程序集的一些引用。因此,不能以任何其他方式引用此程序集。

【讨论】:

  • 开始使用谷歌搜索并通过我自己的博客文章的链接找到答案...
  • 仅供参考,MetadataFileReference 已改为 MetadataReference,因此应为 MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll"))
【解决方案2】:

您似乎在引用 PortableClassLibrary。可移植类库从“System.Runtime.dll”中获取一些基本类型(如对象/字符串/等)。但是,在桌面框架中,这些来自 mscorlib.dll。当您使用typeof(object).Assembly 时,您将获得Roslyn 自己的object 版本。由于 Roslyn 不是作为可移植类库构建的,它是来自 mscorlib 的类库,并且与您的其他引用的身份不匹配。

【讨论】:

  • 这个答案听起来很有效。你怎么能看到我引用了一个 PCL,它是来自引用的 mscorlib 的 publickkey 吗?我在问,因为我没有在我的应用程序中引用任何 PCL(故意)。我真的很想参考 mscorlib 的实际桌面/IIS 版本。我发现当添加 System.Runtime 外观 dll (stackoverflow.com/questions/12349189/…) 时,Roslyn 实际上编译了我的代码。太糟糕了,该帖子的程序集绑定重定向似乎不起作用,因为这有点清洁。
  • 我检查了引用的 mscorlib.dll 的路径,它是 C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\mscorlib.dll,看起来像“真正的”.NET 4 程序集
  • 我从您需要 System.Runtime.dll 的事实中猜到了。绑定重定向不起作用,因为 (1) 它们只能重定向到同一程序集的不同版本,以及 (2) 它们控制运行时行为,而不是编译器行为。您可以通过查看 ildasm.exe 中的外部部分来查看要添加的其他哪些引用需要 System.Runtime
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多