我正在使用" InternalsVisibleTo"带有程序集的属性,用于将内部方法/类公开给我的单元测试项目。
我现在需要将该程序集安装到GAC中,因此我需要给它一个强名称。当我尝试这样做时,我在Visual Studio中收到以下错误。
强名称签名程序集必须在其InternalsVisibleTo声明
中指定公钥
谷歌的一点点让我看到了下面的文章:
https://msdn.microsoft.com/en-us/library/bb763089.aspx
本文指出:
"确定强名友人程序集的公钥。"
本文未说明如何确定公钥。我在哪里可以找到装配的公钥?此外,一旦我有公钥,这是否是声明属性的正确方法?
[assembly: InternalsVisibleTo("Namespace.Assembly.Example.Name, PublicKey=ThePublicKey")]
答案 0 :(得分:42)
更新2019年5月:它与Visual Studio 2019完美配合。
对于使用Visual Studio 2017的任何人,都有最新的方法:
从我们心爱的IDE中,转到" 工具>外部工具...... "和" 添加"这些设置的新工具:
应用/确定这些更改。
在"解决方案资源管理器" 点击您的项目程序集名称,然后前往" 工具>获取PublicKey "。 “输出”窗口应显示(很长)公钥以及公共令牌密钥。
最后,在包含要公开的内部类(即测试项目)的项目中,打开" AssemblyInfo.cs "文件并添加以下行:
[assembly:InternalsVisibleTo(" MyCompany.SolutionName.ProjectName,PublicKey = 将您的公钥粘贴到此处")]
/!\您必须从公钥中删除换行符。
它对我来说非常有用,所以希望它能为你做到这一点!
答案 1 :(得分:17)
使用InternalsVisibleTo
与强烈签名的汇编你的朋友"程序集也必须强烈签名。需要将测试程序集的公共标记指定为InternalsVisibleTo
值的一部分。
请注意,该属性在编译时不用于程序集的实际验证 - 它仅指定运行时检查(以及朋友程序集的编译时检查)应验证该标识。因此,如果 需要编译主程序集,则可以指定任何公钥标记(例如,在Web.Config中的所有程序集引用中找到的Microsoft组件中的一个)。
通常,因为您要签署程序集,所以您知道公钥。即如果您有snk文件,则sn -t youSnk.snk
将显示公钥。或者,您可以按照Getting Public Key Token of Assembly Within Visual Studio中的步骤配置VS,以显示使用sn -Tp {path to assembly}
从程序集获取公钥的任何程序集的公共令牌。 (如果文档已经过去,则将步骤复制到other answer to this question)
答案 2 :(得分:1)
如果您没有测试发布配置,这是一个简单的解决方法:
#if DEBUG
[assembly: InternalsVisibleTo("TestProjNamespace")]
#endif
答案 3 :(得分:0)
我使用经典小说电影中的一个古老的好方法:“黑客总是在第二次尝试中猜测密码”。这是一种简单的技术,除了您已有的工具之外,不需要任何工具 - 一些单元测试框架。是的,必须对被测组件进行签名,正如这里多次提到的那样。
将下面的类复制并粘贴到您的测试 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());
}
}
这里的想法很简单:测试在第一次运行时失败,但会显示测试程序集的正确公钥。要仔细检查是否将“Swordfish”替换为您所获得的实际值,请第二次运行测试以确保它是绿色的,您就在这里。