94

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Luka
  • 4,075
  • 3
  • 35
  • 61
  • 5
    Anywhere, pick one. If you want it in a file named AssemblyInfo.cs then just add it. – Hans Passant Mar 15 '17 at 13:54
  • But I read that AssemblyInfo file is obsolete in new VS2017 .csproj project files. – Luka Mar 15 '17 at 14:34
  • 2
    Not exactly, the *content* is no longer relevant. The attributes are now auto-generated at build time from the Project > Properties > Package settings. That means you can now add this file yourself and do whatever you want with it. If you don't want to add it then that's fine too, *pick one*. – Hans Passant Mar 15 '17 at 14:41
  • 5
    @HansPassant would it be possible for you to formulate a full answer (with examples) for this, or point to some documentation? Your comment makes it seem like you can put the attribute either in AssemblyInfo.cs or directly in the csproj project file - however I can't get Visual Studio to recognize it and successfully compile code when putting the attribute in csproj. I also cannot for the life of me find a full csproj reference listing all the available properties. Best I can find is this: https://msdn.microsoft.com/en-us/library/bb629394.aspx – Aerendel Mar 30 '17 at 20:01

3 Answers3

198

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>
thevioletsaber
  • 143
  • 2
  • 11
Ivan Zaruba
  • 4,236
  • 5
  • 20
  • 29
  • 21
    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. – Daniel Gimenez Apr 27 '18 at 14:59
  • Is there any official documentation for this approach that you could link to? – julealgon Oct 29 '18 at 17:10
  • 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 https://github.com/dotnet/sdk/blob/release/2.1/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.GenerateAssemblyInfo.targets#L119-L122 – Ivan Zaruba Oct 30 '18 at 09:23
  • 8
    This should be the accepted answer, as the question states to add InternalsVisibleTo to .csproj file. – yurislav Jan 16 '19 at 08:48
  • 6
    This might be obvious, but it might be worth nothing that this won't work if you have `GenerateAssemblyVersionAttribute` set to `false` – Cocowalla Apr 16 '19 at 08:00
  • 9
    Alternative to `($MSBuildProjectName)` is `$(AssemblyName)` in the event your project name is different than your assembly. – Andy Danger Gagne May 13 '19 at 14:50
  • No need to use `PublicKey`in this case? – dashesy Dec 17 '19 at 19:36
  • 1
    @dashesy, this approach changes nothing as if you have used an attribute. You will need a <_Parameter1>BlaBla, PublicKey=Bla for a signed assembly. – Ivan Zaruba Dec 18 '19 at 09:39
  • 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: ``. My test naming convention for a project called `Foo` is `Foo.Tests`. This condition is built with that in mind. – void.pointer Apr 23 '22 at 15:17
88

As of .NET 5 (and newer .NET versions) 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.

Alves RC
  • 1,778
  • 14
  • 26
46

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>")]
Pang
  • 9,564
  • 146
  • 81
  • 122