How to use [InternalsVisibleTo] attribute in .NET SDK projects

Sat, Sep 24, 2022 2-minute read

Introduction

Often you want to test internal methods of a class library you are using - this could be because you have internal helper methods that you would like to test in isolation, i.e. proper unit tests.

Before .NET SDK project type was introduced the way to do this was to add a line to the AssemblyInfo.cs file:

[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("MyLibrary.Tests")]

This would allow your MyLibrary.Tests project to see and access internal methods/properties etc.

With the new SDK project type AssemblyInfo is no longer part of the project - and is auto generated based on both convention and data from the csproj file.

So to be able to add [InternalsVisibleTo] you have two options:

Given the following project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netstandard2.1</TargetFramework>
  </PropertyGroup>
</Project>

You disable the creation of AssemblyInfo.cs by adding the following snippet <GenerateAssemblyInfo>false</GenerateAssemblyInfo> to the csproj file:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Inside the <Project> tag

That will allow you to add a AssemblyInfo.cs file and control it the old fashioned way.

The better solution is to add the information directly to the csproj file.

This is done in different ways depending on what target framework you are using.

Below .NET 5

Up until .NET 5 you have to add this to your csproj:

<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
   <_Parameter1>MyLibrary.Tests</_Parameter1>
</AssemblyAttribute>

Also inside the <Project> tag.

.NET 5 and forward

From .NET5 you can add this to your csproj:

<ItemGroup>
  <InternalsVisibleTo Include="MyLibrary.Tests" />
</ItemGroup>

But remember only if your <TargetFramework> is net5.0 or higher

I think this is a much better solution because it promotes the InternalsVisibleTo as a top level item in the csproj file, instead of being a kind of weird step.