【发布时间】: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<T> : IDisposable
因此,我现在收到此错误:
(21,6): error CS0404: Cannot apply attribute class 'System.Composition.Export<T>' because it is generic
由于某种原因,代码现在想要使用 System.Composition.Runtime.Export<T> 而不是在 System.Composition.AttributeModel 程序集中定义的 ExportAttribute。
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
【问题讨论】:
-
您的 cmets 可能具有误导性。据我所知,
System.Runtime.ProfileOptimization在mscorlib中,而不是在System.Runtime程序集中。 -
你说得对,我自己也是这么想的。似乎没有
System.Runtime程序集,所有东西都应该在mcorslib中可用。刚刚从帖子和来源中删除了该行,所以它有点干净。 -
这听起来像是在为 csc 使用
/nostdlib选项时。 -
您的回答有助于解决我的问题。谢谢!您不想将其作为真实答案发布,而不是作为问题的一部分发布吗?我几乎忽略了它... P.S.恭喜你获得 2226 SO 积分 ;)
-
好点!我将其作为单独的答案发布。