Roslyn没有引用System.Runtime

Jan*_*n_V 22 c# roslyn

我正在开发一个项目,我们正在使用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'.
Run Code Online (Sandbox Code Playgroud)

看到这些错误,我认为我没有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();
}
Run Code Online (Sandbox Code Playgroud)

编译本身:

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);
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些明显的东西吗 看起来成功编译的所有先决条件都得到满足,但显然它们不是.

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

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑 我在搜索中有所提升.错误消息中指定的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();
}
Run Code Online (Sandbox Code Playgroud)

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

这确实引入了不同的错误.你可以自己查看,有一个通用的Export类System.Composition.Runtime: public sealed class Export<T> : IDisposable 因为这个我现在收到这个错误:

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

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

EDIT2

我可以确认上面的代码使用System.Composition.Export<T>而不是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
Run Code Online (Sandbox Code Playgroud)

Kev*_*lch 10

您似乎正在引用PortableClassLibrary.Portable Class Libraries从"System.Runtime.dll"中获取一些基本类型(如object/string/etc).但是,在桌面框架中,这些来自mscorlib.dll.当你使用时typeof(object).Assembly,你会获得Roslyn自己的版本object.由于Roslyn不是构建为可移植类库,而是来自mscorlib,并且与其他引用的标识不匹配.


Jan*_*n_V 8

根据Dejan在评论部分的要求,我会将答案(我的问题)作为一个真正的答案发布.


我发现了问题所在!编译器一直都是正确的.一个博客帖子smack0007触发我尝试别的东西.而不是使用Facade DLL,尝试手动引用必要的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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 开始谷歌搜索,并找到答案,并带有指向我自己的博客文章的链接... (2认同)
  • 仅供参考,MetadataFileReference 已更改为 MetadataReference,因此它应该是 MetadataReference.CreateFromFile(Path.Combine( assemblyPath, "System.Runtime.dll")) (2认同)

dad*_*dhi 6

预定义的参考文献列表对我不起作用。

但从受AppDomain帮助者那里得到它们:

public static readonly List<PortableExecutableReference> References = 
    AppDomain.CurrentDomain.GetAssemblies()
        .Where(_ => !_.IsDynamic && !string.IsNullOrWhiteSpace(_.Location))
        .Select(_ => MetadataReference.CreateFromFile(_.Location))
        .Concat(new[]
        {
            // add your app/lib specifics, e.g.:                      
            MetadataReference.CreateFromFile(typeof(MyType).Assembly.Location),
        })
        .ToList();
Run Code Online (Sandbox Code Playgroud)

我在这个有用的存储库中找到了答案: https: //github.com/andrewlock/NetEscapades.EnumGenerators