Visual Studio 2017 and the new .csproj InternalsVisibleTo

18,792

Solution 1

To clarify Hans Passant's comment above, you simply have to add InternalsVisibleTo to any cs file in your project. For example, I created an AssemblyInfo.cs file in the root of the project and then added the following content (only):

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=<ADD_KEY_HERE>")]

Solution 2

Just in case anyone would like to put InternalsVisibleTo within a .csproj file instead of AssemblyInfo.cs (a possible scenario is to have a naming convention between a project under test and a test project), you can do it like this:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
      <_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

Having this the following code will be generated

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyProject.Test")]

inside auto-generated AssemblyInfo.cs (e.g. for Debug configuration and .NET Standard 2.0 target)

/obj/Debug/netstandard2.0/MyProject.AssemblyInfo.cs

Additional Info

In case you're on .NET Core 3.1 and this approach isn't working, you may have to explicitly generate assembly info by adding the following to your .csproj file:

<PropertyGroup>
  <!-- Explicitly generate Assembly Info -->
  <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>

Solution 3

As of .NET 5 this actually works once added to your csproj:

<ItemGroup>
  <InternalsVisibleTo Include="YourProject.Tests.Unit" />
</ItemGroup>

Work and discussion around this feature can be seen on this PR on dotnet's GitHub repo.

Share:
18,792
Luka
Author by

Luka

Updated on June 14, 2022

Comments

  • Luka
    Luka almost 2 years

    Where do I put InternalsVisibleTo from AssemblyInfo in the new Visual Studio 2017 .csproj project file?

  • Daniel Gimenez
    Daniel Gimenez about 6 years
    This technique is very useful. If you have multiple projects you can use a directory.build.props file in the solution root and have it apply to all of your projects.
  • julealgon
    julealgon over 5 years
    Is there any official documentation for this approach that you could link to?
  • Ivan Zaruba
    Ivan Zaruba over 5 years
    Not sure this approach is documented since it is rather customization than common practice. But if you would like to know how this works, please refer to the Microsoft.NET.GenerateAssemblyInfo.targets file github.com/dotnet/sdk/blob/release/2.1/src/Tasks/…
  • yurislav
    yurislav over 5 years
    This should be the accepted answer, as the question states to add InternalsVisibleTo to .csproj file.
  • Cocowalla
    Cocowalla about 5 years
    This might be obvious, but it might be worth nothing that this won't work if you have GenerateAssemblyVersionAttribute set to false
  • Andy Danger Gagne
    Andy Danger Gagne almost 5 years
    Alternative to ($MSBuildProjectName) is $(AssemblyName) in the event your project name is different than your assembly.
  • dashesy
    dashesy over 4 years
    No need to use PublicKeyin this case?
  • Ivan Zaruba
    Ivan Zaruba over 4 years
    @dashesy, this approach changes nothing as if you have used an attribute. You will need a <_Parameter1>BlaBla, PublicKey=Bla</_Parameter1> for a signed assembly.
  • void.pointer
    void.pointer about 2 years
    If you do end up adding this to your Directory.Build.props files, you want to make sure it's excluded from test projects. The following condition on my ItemGroup worked for me: <ItemGroup Condition="!$(ProjectName.EndsWith('.Tests'))">. My test naming convention for a project called Foo is Foo.Tests. This condition is built with that in mind.