输出程序集()的公钥与授予程序集中 InternalsVisibleTo 特性指定的公钥不匹配 - 小众知识

输出程序集()的公钥与授予程序集中 InternalsVisibleTo 特性指定的公钥不匹配

2013年01月27日 14:18:05 苏内容
  标签: 公钥
阅读:7328

严重性 代码 说明 项目 文件 禁止显示状态


错误 CS0281 友元访问权限由“Xceed.Document.NET, Version=1.6.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4”授予,但是输出程序集('')的公钥与授予程序集中 InternalsVisibleTo 特性指定的公钥不匹配。 Xceed.Words.NET D:Xceed.Words.NETDocX.cs 97 活动




由于公钥文件引入不正确导致,仔细判断


#pragma warning disable 1699


[assembly: AssemblyDelaySign( false )]


[assembly: AssemblyKeyFile( @"sn.snk" )]


[assembly: AssemblyKeyName( "" )]


#pragma warning restore 1699


注意,sn.snk相对目录为相对于工程文件.csproj


InternalsVisibleToAttribute——把internal成员暴露给指定的友元程序集

友元程序集简介

我们知道一个类中被定义为internal的成员(包括类型、方法、属性、变量、事件)是只能在同一个程序集中被访问到的(当然了,我这里说的是正常的方式,不包括通过反射来访问)。这个规则在.NET2.0稍稍被打破,InternalsVisibleToAttribute允许我们设置一个程序集的internal的成员可以被特定的成员访问到。我们把包含这些internal成员的程序集称为源程序集(source assembly),而这个设定的程序集称为友元程序集(friend assembly)。


友元程序集使用

这个Attribute是是使用于程序集级别的。


using System;


[assembly:InternalsVisibleTo("FriendAssembly")]public class Class1{    internal string Name { get; set; }

}

那这样FriendAssembly程序引用了该程序集之后,就可以访问到internal的Name属性。

一般这个assembly:InternalsVisibleTo("FriendAssembly")放在AssemblyInfo.cs里比较好,毕竟它是程序集级别的。


什么情况下使用InternalsToVisibleTo

其实,在一般的应用中也用不上这个Attribute,而且我们也不应该滥用这个属性。因为一般情况下,设计合理的程序集是不需要对外开放internal成员的访问的。

但是单元测试的场景是可以利用一下这个特性的。有了这个特性,我们可以指定让单元测试的代码可以访问那些internal成员,这样就可以对这些成员进行单元测试了。不过这样需要在源程序集里将友元程序集的名称写死了,这回造成一些安全问题。可以通过引入签名程序集来保证安全。


InternalsToVisibleTo和签名程序集

可以直接给InternalsVisibleTo指定友元程序集的名称和公钥。

使用VS开发者命令行生成FriendAssembly的公钥:


sn -Tp FriendAssembly.dll

给源程序集指定友元程序集的名称以及公钥:


[assembly:InternalsVisibleTo("FriendAssembly, PublicKey=00200220202......3a3b3c")]

实际上,由于友元程序集会引用源程序集,而且签名的程序集引用一个未签名的程序集、签名的程序集也不能指定一个未签名的友元程序集,所以其中任何一个程序集签名了,那它们就都需要进行签名。


扩展阅读