はじめに
今回はInternalsVisibleTo
という属性(Attribute)について紹介したいと思います。
皆さんご存知かと思いますが、internal
を利用することで同一アセンブリでしかアクセスできないようにすることができます。
internal 型またはメンバーは、次の例のように、同じアセンブリ内のファイルでのみアクセスできます。
internal - C# リファレンス | Microsoft Docs
UnityではAssembly Definition Files
を利用するとアセンブリを分けることができる訳ですが、特にテスト周りでinternal
にもアクセスしたくなることが多々あるかと思います。
アセンブリの定義 - Unity マニュアル
それを可能にするのが今回紹介するInternalsVisibleTo
になります。
InternalsVisibleTo
通常は現在のアセンブリ内でのみ参照できる型が、指定したアセンブリから参照可能であることを指定します。
InternalsVisibleToAttribute クラス (System.Runtime.CompilerServices) | Microsoft Docs
[System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)] public sealed class InternalsVisibleToAttribute : Attribute
使い方は簡単で、ファイルの冒頭に以下のようなコードを書けばOKです。
using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Tests")]
こうすることで引数に記述したアセンブリは、InternalsVisibleTo
を記載したアセンブリの全てのinternal
にアクセス可になります。
一つ注意点なのは、InternalsVisibleTo
を使われる側のアセンブリに記述するということですね。
たまに私も逆だったけと戸惑うことがあったりなかったり。
Unity公式の使用例
Unityの実装ではAssemblyInfo.cs
というファイルが用意され、中にInternalsVisibleTo
を列挙しているようです。
// Unity C# reference source // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System.Runtime.CompilerServices; using UnityEngine; // ADD_NEW_PLATFORM_HERE [assembly: InternalsVisibleTo("Unity.LiveNotes")] [assembly: InternalsVisibleTo("Unity.Burst")] [assembly: InternalsVisibleTo("Unity.Burst.Editor")] [assembly: InternalsVisibleTo("Unity.Cloud.Collaborate.Editor")] [assembly: InternalsVisibleTo("Unity.CollabProxy.Editor")] [assembly: InternalsVisibleTo("Unity.CollabProxy.EditorTests")] [assembly: InternalsVisibleTo("Unity.CollabProxy.UI")] [assembly: InternalsVisibleTo("Unity.CollabProxy.UI.Tests")] [assembly: InternalsVisibleTo("Unity.CollabProxy.Client")] [assembly: InternalsVisibleTo("Unity.CollabProxy.Client.Tests")] // 以下省略
UnityCsReference/AssemblyInfo.cs at master · Unity-Technologies/UnityCsReference · GitHub
またアセンブリを見ても、だいたいEditor
やTests
周りっぽいですね。
使用例
InternalsVisibleTo
は対象アセンブリ内であればどこに書いてもよいのですが、AssemblyInfo.cs
を用意するのが割と主なんですかね?
断言できませんが、割と見る気はします。
また実装する際InternalsVisibleTo
の引数の文字列は、Assembly Definition Files
に記述したName
と一致させてあげればOKです。
using System.Runtime.CompilerServices; using UnityEngine; [assembly: InternalsVisibleTo("Tests")]