如何将 "InternalsVisibleTo" 属性与强命名程序集一起使用?
How to use "InternalsVisibleTo" attribute with Strongly named assembly?
我将 "InternalsVisibleTo" 属性与程序集一起使用,以将内部 methods/classes 公开给我的单元测试项目。
我现在需要将该程序集安装到 GAC 中,因此我需要为其指定一个强名称。当我尝试这样做时,我在 Visual Studio 中收到以下错误。
Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations
通过谷歌搜索,我找到了以下文章:
https://msdn.microsoft.com/en-us/library/bb763089.aspx
本文指出:
"Determine the public key for the strong-named friend assembly."
本文没有说如何确定public键。在哪里可以找到程序集的 public 键?另外,一旦我有了 public 键,这是声明属性的正确方法吗?
[assembly: InternalsVisibleTo("Namespace.Assembly.Example.Name, PublicKey=ThePublicKey")]
要将 InternalsVisibleTo
与强签名程序集一起使用,您的“朋友”程序集也必须是强签名的。 Public 测试程序集的令牌需要指定为 InternalsVisibleTo
值的一部分。
请注意,该属性不用于编译时程序集的实际验证 - 它仅指定 运行 时检查(以及朋友程序集的编译时检查)应该验证该身份。因此,如果您 只是 需要编译您的主程序集,您可以指定任何 public 密钥令牌(即来自 Web.Config 中所有程序集引用的 Microsoft 程序集之一例如)。
通常,因为您要签署程序集,所以您会知道 public 密钥。 IE。如果你有 snk 文件,那么 sn -t youSnk.snk
会显示 public 键。或者您可以按照 Getting Public Key Token of Assembly Within Visual Studio to configure your VS to show public token for any assembly which uses sn -Tp {path to assembly}
to get public key from the assembly. (If document is gone steps are copied to the )
中的步骤操作
2019 年 5 月更新: 它与 Visual Studio 2019 完美配合。
2022 年 5 月更新: 如@Igor Meszaros 所述,它也适用于 Visual Studio 2022。
对于正在使用 Visual Studio 2017 的任何人,这里有最新的方法:
来自我们心爱的 IDE,转到“工具 > 外部工具...”和“添加”具有这些设置的新工具:
- 标题:获取Public密钥
- 命令:“C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\sn.exe” (/!\ 选择与您的程序集 NETFX 版本匹配的 NETFX 工具版本,这里是 4.6.2)
- 参数:-Tp $(TargetPath)
- 选中“使用输出 window”复选框
Apply/OK 那些变化。
在“解决方案资源管理器”中 单击您的项目程序集名称,然后转到“工具 > 获取 Public密钥”。
输出 window 应该显示(很长)Public 密钥,以及 Public 令牌密钥。
最后,在你要暴露的包含内部class的项目(即测试项目)中,打开“AssemblyInfo.cs”文件并添加行:
[程序集:InternalsVisibleTo("MyCompany.SolutionName.ProjectName, PublicKey=在此处粘贴您的 public 键") ]
/!\ 您必须从 public 键中删除换行符。
它对我来说效果很好,所以希望它对你也有帮助!
我使用了 class 科幻电影中的一个古老的好方法:“黑客总是在第二次尝试中猜测密码”。这是一种简单的技术,除了您已经拥有的一些单元测试框架之外,它不需要任何工具。是的,必须对被测程序集进行签名,如此处多次提及。
复制下面的 class 并将其粘贴到您的测试 DLL 中。它是 xUnit 测试,但同样的方法适用于任何单元测试框架。
public class FindOutAssemblyPublicKey
{
const string AssemblyPK = "Swordfish";
/// <summary>
/// Fake test to find out a correct PublicKey in InternalsVisibleTo for assembly under test.
/// </summary>
[Fact]
public void AssemblyPublicKeyIsAsExpected()
{
byte[] publicKey = GetType().Assembly.GetName().GetPublicKey();
var sb = new StringBuilder();
foreach (byte @byte in publicKey)
sb.AppendFormat("{0:x2}", @byte);
// Set breakpoint here to find out what's in sb
Assert.Equal(AssemblyPK, sb.ToString());
}
}
这里的想法很简单:一开始测试失败 运行 但会显示测试程序集的正确 public 密钥。要仔细检查用您得到的实际值替换“Swordfish”,运行 第二次测试以确保它是绿色的,这就是您的位置。
我将 "InternalsVisibleTo" 属性与程序集一起使用,以将内部 methods/classes 公开给我的单元测试项目。
我现在需要将该程序集安装到 GAC 中,因此我需要为其指定一个强名称。当我尝试这样做时,我在 Visual Studio 中收到以下错误。
Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations
通过谷歌搜索,我找到了以下文章:
https://msdn.microsoft.com/en-us/library/bb763089.aspx
本文指出:
"Determine the public key for the strong-named friend assembly."
本文没有说如何确定public键。在哪里可以找到程序集的 public 键?另外,一旦我有了 public 键,这是声明属性的正确方法吗?
[assembly: InternalsVisibleTo("Namespace.Assembly.Example.Name, PublicKey=ThePublicKey")]
要将 InternalsVisibleTo
与强签名程序集一起使用,您的“朋友”程序集也必须是强签名的。 Public 测试程序集的令牌需要指定为 InternalsVisibleTo
值的一部分。
请注意,该属性不用于编译时程序集的实际验证 - 它仅指定 运行 时检查(以及朋友程序集的编译时检查)应该验证该身份。因此,如果您 只是 需要编译您的主程序集,您可以指定任何 public 密钥令牌(即来自 Web.Config 中所有程序集引用的 Microsoft 程序集之一例如)。
通常,因为您要签署程序集,所以您会知道 public 密钥。 IE。如果你有 snk 文件,那么 sn -t youSnk.snk
会显示 public 键。或者您可以按照 Getting Public Key Token of Assembly Within Visual Studio to configure your VS to show public token for any assembly which uses sn -Tp {path to assembly}
to get public key from the assembly. (If document is gone steps are copied to the
2019 年 5 月更新: 它与 Visual Studio 2019 完美配合。
2022 年 5 月更新: 如@Igor Meszaros 所述,它也适用于 Visual Studio 2022。
对于正在使用 Visual Studio 2017 的任何人,这里有最新的方法:
来自我们心爱的 IDE,转到“工具 > 外部工具...”和“添加”具有这些设置的新工具:
- 标题:获取Public密钥
- 命令:“C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\sn.exe” (/!\ 选择与您的程序集 NETFX 版本匹配的 NETFX 工具版本,这里是 4.6.2)
- 参数:-Tp $(TargetPath)
- 选中“使用输出 window”复选框
Apply/OK 那些变化。
在“解决方案资源管理器”中 单击您的项目程序集名称,然后转到“工具 > 获取 Public密钥”。 输出 window 应该显示(很长)Public 密钥,以及 Public 令牌密钥。
最后,在你要暴露的包含内部class的项目(即测试项目)中,打开“AssemblyInfo.cs”文件并添加行:
[程序集:InternalsVisibleTo("MyCompany.SolutionName.ProjectName, PublicKey=在此处粘贴您的 public 键") ]
/!\ 您必须从 public 键中删除换行符。
它对我来说效果很好,所以希望它对你也有帮助!
我使用了 class 科幻电影中的一个古老的好方法:“黑客总是在第二次尝试中猜测密码”。这是一种简单的技术,除了您已经拥有的一些单元测试框架之外,它不需要任何工具。是的,必须对被测程序集进行签名,如此处多次提及。
复制下面的 class 并将其粘贴到您的测试 DLL 中。它是 xUnit 测试,但同样的方法适用于任何单元测试框架。
public class FindOutAssemblyPublicKey
{
const string AssemblyPK = "Swordfish";
/// <summary>
/// Fake test to find out a correct PublicKey in InternalsVisibleTo for assembly under test.
/// </summary>
[Fact]
public void AssemblyPublicKeyIsAsExpected()
{
byte[] publicKey = GetType().Assembly.GetName().GetPublicKey();
var sb = new StringBuilder();
foreach (byte @byte in publicKey)
sb.AppendFormat("{0:x2}", @byte);
// Set breakpoint here to find out what's in sb
Assert.Equal(AssemblyPK, sb.ToString());
}
}
这里的想法很简单:一开始测试失败 运行 但会显示测试程序集的正确 public 密钥。要仔细检查用您得到的实际值替换“Swordfish”,运行 第二次测试以确保它是绿色的,这就是您的位置。