skb*_*skb 70 .net attributes internalsvisibleto
我正在尝试使用InternalsVisibleToassembly属性使我的单元测试项目可以看到.NET类库中的内部类.出于某种原因,我不断收到一条错误消息:
由于其保护级别,"MyClassName"无法访问
两个程序集都已签名,并且我在属性声明中列出了正确的密钥.有任何想法吗?
Joe*_*Joe 96
您确定要在属性中指定正确的公钥吗?请注意,您需要指定完整的公钥,而不仅仅是公钥标记.它看起来像:
[assembly: InternalsVisibleTo("MyFriendAssembly,
PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73
F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66
A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519
674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C140
6E2F553073FF557D2DB6C5")]
Run Code Online (Sandbox Code Playgroud)
它是320左右的十六进制数字.不确定为什么需要指定完整的公钥 - 可能只使用其他程序集引用中使用的公钥标记,这样可以更容易欺骗朋友程序集的标识.
Joh*_*yer 39
另一个可能的"问题":您在其中指定的朋友程序集的名称InternalsVisibleToAttribute必须与朋友程序集的名称完全匹配,如朋友的项目属性中所示(在"应用程序"选项卡中).
就我而言,我有一个项目Thingamajig和一个伴侣项目ThingamajigAutoTests(名称已更改以保护有罪),这两个项目都生成了未签名的程序集.我适当添加的属性[assembly: InternalsVisibleTo( "ThingamajigAutoTests" )]到Thingamajig\AssemblyInfo.cs文件,并评论出AssemblyKeyFile和AssemblyKeyName如上所述的属性.该Thingamajig项目建设得很好,但其内部成员顽固地拒绝出现在自动测试项目中.
经过多次努力,我重新检查了ThingamajigAutoTests项目属性,发现程序集名称被指定为"ThingamajigAutoTests.dll".宾果游戏 - 我在InternalsVisibleTo属性中的程序集名称中添加了".dll"扩展名,并且这些部分已经到位.
有时它是最小的东西......
小智 36
如果您的程序集未签名,但仍然遇到相同的错误,请检查AssemblyInfo.cs文件中是否有以下任一行:
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
Run Code Online (Sandbox Code Playgroud)
如果存在这些行中的任何一行(或两者),则属性选项卡仍会将程序集显示为无符号,但InternalsVisibleTo属性将具有这些行的程序集视为强签名.只需删除(或注释掉)这些行,它就可以正常工作了.
Col*_*ond 12
值得注意的是,如果"朋友"(测试)程序集是用C++/CLI编写的,而不是C#/ VB.Net那么你需要使用以下代码:
#using "AssemblyUnderTest.dll" as_friend
Run Code Online (Sandbox Code Playgroud)
而不是项目参考或通常的#using声明.出于某种原因,在项目参考UI中无法执行此操作.
尽管使用AssemblyInfo文件和添加InternalsVisibleTo仍然有效,但现在的首选方法(据我所知)是ItemGroup在项目csproj文件中使用 an ,如下所示:
<ItemGroup>
<InternalsVisibleTo Include="My.Project.Tests" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
如果需要 PublicKey,也可以添加此属性。
小智 5
这是我用来快速生成此属性的宏.它有点hacky,但它的工作原理.在我的机器上.当最新签名的二进制文件在/bin/debug.时 Etc模棱两可等等.无论如何,你可以看到它是如何获得密钥的,所以它会给你一个提示.随着时间的推移,修复/改进.
Sub GetInternalsVisibleToForCurrentProject()
Dim temp = "[assembly: global::System.Runtime.CompilerServices." + _
"InternalsVisibleTo(""{0}, publickey={1}"")]"
Dim projs As System.Array
Dim proj As Project
projs = DTE.ActiveSolutionProjects()
If projs.Length < 1 Then
Return
End If
proj = CType(projs.GetValue(0), EnvDTE.Project)
Dim path, dir, filename As String
path = proj.FullName
dir = System.IO.Path.GetDirectoryName(path)
filename = System.IO.Path.GetFileNameWithoutExtension(path)
filename = System.IO.Path.ChangeExtension(filename, "dll")
dir += "\bin\debug\"
filename = System.IO.Path.Combine(dir, filename)
If Not System.IO.File.Exists(filename) Then
MsgBox("Cannot load file " + filename)
Return
End If
Dim assy As System.Reflection.Assembly
assy = System.Reflection.Assembly.Load(filename)
Dim pk As Byte() = assy.GetName().GetPublicKey()
Dim hex As String = BitConverter.ToString(pk).Replace("-", "")
System.Windows.Forms.Clipboard.SetText(String.Format(temp, assy.GetName().Name, hex))
MsgBox("InternalsVisibleTo attribute copied to the clipboard.")
End Sub
Run Code Online (Sandbox Code Playgroud)