當前位置: 妍妍網 > 碼農

InternalsVisibleTo 的用法

2024-02-10碼農

InternalsVisibleTo 的用法

Intro

之前寫過一篇關於 InternalsVisibleTo 的文章,沒看過的朋友可以移步閱覽

最近發現遺漏了針對 PublicKey 的一種寫法,而且發現有些 dotnet 的類別庫裏還在使用傳統的 [assembly:InternalsVisibleTo] 或者 <AssemblyAttribute> ,趁機蹭了幾個 PR 的 contribution

因為之前的文章裏已經介紹了一些 InternalsVisibleTo 的使用,這裏不再詳細介紹之前的用法了

主要介紹透過 MS Build 在計畫檔( *.csproj )或者內容檔 *.props/targets 中的配置

InternalsVisibleTo Item

從 .NET 5 開始我們可以在計畫檔中聲明 InternalsVisibleTo 最後在 build 的時候會生成 [assembly:InternalsVisibleToAttribute] ,舉個例子:

<ItemGroup>
<InternalsVisibleToInclude="UnitTest" />
</ItemGroup>

反編譯生成的結果如下:

可以看到編譯之後自動生成了 [assembly:InternalsVisibleTo] attribute

針對有 PublicKey 需要配置情況可以使用下面幾種寫法

<InternalsVisibleToInclude="UnitTest, PublicKey=xxxxx" />

<InternalsVisibleToInclude="UnitTest"Key="xxxxx" />

<PropertyGroup>
<PublicKey>xxxxx</PublicKey>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleToInclude="UnitTest" />
</ItemGroup>

最後這種配置 PublicKey property 的形式上次的文章中漏掉了,最近的幾個 PR 也是用到了這個特性來簡化 PublicKey 的配置,因為 PublicKey 通常比較長,難以閱讀,透過定義 PublicKey property 就只需要配置一次就可以大大簡化配置了,這在有多個 InternalsVisibleTo 的計畫時會更加的方便,感興趣的朋友可以參考文末的 PR 連結

最後從 .NET 7 開始,我們也可以使用 PublicKey 代替 Key 更加符合 public key 的命名規範

<InternalsVisibleToInclude="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