所以我正在开发一个基于Roslyn的前端编译器,它解析一个C#解决方案,在语法树上执行重写以消除我的DSL的一些构造,然后使用Roslyn API来编译和发出可执行文件/ dll.在给出编译的情况下,最后一部分非常简单地完成(为清楚起见省略了一些细节):
var compilation = project.GetCompilationAsync().Result;
var compilationOptions = new CSharpCompilationOptions(outputKind,
compilation.Options.ModuleName, compilation.Options.MainTypeName,
compilation.Options.ScriptClassName, null,
compilation.Options.OptimizationLevel, compilation.Options.CheckOverflow,
false, compilation.Options.CryptoKeyContainer,
compilation.Options.CryptoKeyFile, compilation.Options.CryptoPublicKey,
compilation.Options.DelaySign, Platform.AnyCpu,
compilation.Options.GeneralDiagnosticOption,
compilation.Options.WarningLevel,
compilation.Options.SpecificDiagnosticOptions,
compilation.Options.ConcurrentBuild,
compilation.Options.XmlReferenceResolver,
compilation.Options.SourceReferenceResolver,
compilation.Options.MetadataReferenceResolver,
compilation.Options.AssemblyIdentityComparer,
compilation.Options.StrongNameProvider);
var targetCompilation = CSharpCompilation.Create(assemblyFileName,
compilation.SyntaxTrees, compilation.References,
compilationOptions);
EmitResult emitResult = null;
using (var outputFile = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
emitResult = targetCompilation.Emit(outputFile);
if (emitResult.Success)
{
return fileName;
}
}
Run Code Online (Sandbox Code Playgroud)
所以一切都运行得很好,直到我尝试编译一个项目A声明一些内部类/字段的解决方案,然后使用该[assembly: InternalsVisibleTo("...")]属性(在AssemblyInfo.cs文件中)将这些内部的可见性提供给另一个项目B.
使用visual studio直接编译工作非常精细,并允许B查看A的这些内部声明.但是,当我尝试使用Roslyn API编译我的工具时,就像InternalsVisibleTo属性被完全忽略,我收回错误, 如:
error CS0122: ... is inaccessible due to its protection level
这意味着InternalsVisibleTo没有被选中.
我期待Roslyn会自动从解析的项目信息中选择它,但我现在想知道是否必须启用某些特定的编译选项或手动添加一些信息?
我环顾四周,但找不到类似的问题或答案,除非我遗漏了什么.如果需要,我可以提供更多信息.谢谢!
InternalsVisibleTo需要与用于签署其他程序集的公钥完全匹配(或者在未签名程序集的情况下没有公钥)。仔细检查您是否提供了正确的密钥和正确的程序集名称(包括命名空间)。
特别是,在这里,您对完整的公钥感兴趣,而不是公钥令牌。
有关更多信息以及如何为此目的提取公钥,请查看InternalsVisibleToAttribute Class。