如何通过安全地签署公共令牌密钥来使InternalsVisibleTo属性起作用?

pen*_*ake 9 .net c# unit-testing internalsvisibleto visual-studio

我试图通过使用以下内容向我的单元测试项目公开一些内部:

[assembly: InternalsVisibleTo("MyTest")]
Run Code Online (Sandbox Code Playgroud)

但是我收到了错误:

错误1朋友程序集引用MyTest'无效.强名称签名程序集必须在其InternalsVisibleTo声明中指定公钥..../MyClass.cs ...

当我手动分配PublicTokenKey时:

[assembly: InternalsVisibleTo("MyTest, PublicKeyToken=XxxxxYysakf")]
Run Code Online (Sandbox Code Playgroud)

解决方案构建没有任何错误.

  1. 为什么我需要包含公钥令牌?
  2. 我不确定我是否会通过包含公钥令牌来破坏生产中的某些东西.

那么,为我的Test项目分配公钥的最佳和最安全的方法是什么?

Jon*_*son 7

我很惊讶PublicKeyToken甚至可以工作 - 在我的机器上它迫使我使用PublicKey

  1. 您需要公钥令牌的原因是因为强名称的程序集可以放入GAC中 - 它具有很高的信任度.如果任何名为"MyTest"的程序集(可能不受信任 - 例如浏览器中的控件)可能会调用GACed程序集的内部,那将是一个安全漏洞; 它想要公钥来防止这种类型的黑客攻击.

  2. 这不应该破坏生产中的任何东西 - 即使无法找到组件.此属性在编译时使用,而不是在运行时使用.

什么是最安全的方式?

如果您真的担心它会破坏生产代码,请在发布版本期间删除该属性:

#if (DEBUG || TEST)
[assembly: InternalsVisibleTo("MyTest, PublicKeyToken=XxxxxYysakf")] 
#endif
Run Code Online (Sandbox Code Playgroud)

如果你有一些项目需要公钥令牌(并且你有一个密钥对,你应该),你也可以定义一个文件AssemblyInfo.global.cs,并将其作为链接文件添加到你的所有项目中:

class KeyTokens
{
   public const string Global = ", PublicKeyToken=XxxxxYysakf";
}
Run Code Online (Sandbox Code Playgroud)

这简化了事情(特别是如果你需要使用PublicKey真的很长):

#if (DEBUG || TEST)
[assembly: InternalsVisibleTo("MyTest" + KeyTokens.Global)] 
[assembly: InternalsVisibleTo("HisTest" + KeyTokens.Global)] 
[assembly: InternalsVisibleTo("TheirTest" + KeyTokens.Global)] 
#endif
Run Code Online (Sandbox Code Playgroud)