Visual Studio 2017 and the new .csproj InternalsVisibleTo
Asked Answered
D

3

97

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

Denadenae answered 15/3, 2017 at 13:7 Comment(4)
Anywhere, pick one. If you want it in a file named AssemblyInfo.cs then just add it.Leverick
But I read that AssemblyInfo file is obsolete in new VS2017 .csproj project files.Denadenae
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.Leverick
@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: msdn.microsoft.com/en-us/library/bb629394.aspxDelineator
N
47

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>")]
Nildanile answered 3/4, 2017 at 15:22 Comment(0)
I
201

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>
Infrastructure answered 23/4, 2018 at 9:57 Comment(9)
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.Dagnydago
Is there any official documentation for this approach that you could link to?Philemon
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/…Infrastructure
This should be the accepted answer, as the question states to add InternalsVisibleTo to .csproj file.Telltale
This might be obvious, but it might be worth nothing that this won't work if you have GenerateAssemblyVersionAttribute set to falseUnschooled
Alternative to ($MSBuildProjectName) is $(AssemblyName) in the event your project name is different than your assembly.Naraka
No need to use PublicKeyin this case?Greatgrandaunt
@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.Infrastructure
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.Solingen
C
104

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.

Circumgyration answered 5/2, 2021 at 0:20 Comment(0)
N
47

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>")]
Nildanile answered 3/4, 2017 at 15:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.