InternalsVisibleTo
的用法
Intro
之前写过一篇关于 InternalsVisibleTo
的文章,没看过的朋友可以移步阅览 .NET 中的 InternalsVisibleTo
最近发现遗漏了针对 PublicKey
的一种写法,而且发现有些 dotnet 的类库里还在使用传统的 [assembly:InternalsVisibleTo]
或者 <AssemblyAttribute>
,趁机蹭了几个 PR 的 contribution
因为之前的文章里已经介绍了一些 InternalsVisibleTo
的使用,这里不再详细介绍之前的用法了
主要介绍通过 MS Build 在项目文件(*.csproj
)或者属性文件 *.props/targets
中的配置
InternalsVisibleTo
Item
从 .NET 5 开始我们可以在项目文件中声明 InternalsVisibleTo
最后在 build 的时候会生成 [assembly:InternalsVisibleToAttribute]
,举个例子:
<ItemGroup>
<InternalsVisibleTo Include="UnitTest" />
</ItemGroup>
反编译生成的结果如下:
可以看到编译之后自动生成了 [assembly:InternalsVisibleTo]
attribute
针对有 PublicKey
需要配置情况可以使用下面几种写法
<InternalsVisibleTo Include="UnitTest, PublicKey=xxxxx" />
<InternalsVisibleTo Include="UnitTest" Key="xxxxx" />
<PropertyGroup>
<PublicKey>xxxxx</PublicKey>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="UnitTest" />
</ItemGroup>
最后这种配置 PublicKey
property 的形式上次的文章中漏掉了,最近的几个 PR 也是用到了这个特性来简化 PublicKey
的配置,因为 PublicKey
通常比较长,难以阅读,通过定义 PublicKey
property 就只需要配置一次就可以大大简化配置了,这在有多个 InternalsVisibleTo 的项目时会更加的方便,感兴趣的朋友可以参考文末的 PR 链接
最后从 .NET 7 开始,我们也可以使用 PublicKey
代替 Key
更加符合 public key 的命名规范
<InternalsVisibleTo Include="UnitTest" PublicKey="xxxxx" />
More
InternalsVisibleTo
的实现是基于 .NET Core 里的 AssemblyAttribute
来实现的,最终生成 assembly:InternalsVisibleTo
attribute
References
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute?view=net-6.0
https://www.meziantou.net/declaring-internalsvisibleto-in-the-csproj.htm
https://github.com/dotnet/sdk/pull/3439
https://github.com/dotnet/sdk/pull/25000
https://github.com/dotnet/msbuild/issues/7336
https://github.com/dotnet/runtime/blob/3fc61ebb562afc327a8fc6de5c82d76e86bf6f5d/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs#L7
https://github.com/dotnet/sdk/blob/40fbdd1b8774e7a310539ff4114d6a53608f1c3c/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.GenerateAssemblyInfo.targets#L108-L116
https://github.com/rabbitmq/rabbitmq-dotnet-client/pull/1488
https://github.com/fluentassertions/fluentassertions/pull/2575
https://github.com/EasyNetQ/EasyNetQ/pull/1757
https://github.com/StackExchange/StackExchange.Redis/pull/2623