Double-edged sword of InternalsVisibleTo

This post was originally published here.

I’ve had some conversations with both Joe and Elton lately about the InternalsVisibleTo attribute.  From the documentation, the assembly-level InternalsVisibleTo attribute:

Specifies that all nonpublic types in an assembly are visible to another assembly.

This attribute was introduced in C# 2.0, and allows you to specify other assemblies that can see all types and members marked “internal”.  In practice, all assemblies are signed with the same public key, and you’d specify that the unit test assembly can see that assembly.

  • MyProject.Core -> has the “InternalsVisibleTo” attribute defined in the AssemblyInfo.cs file, pointing at the below assembly
  • MyProject.Core.Tests -> is signed with the same public key as the Core assembly

Notice that the “Core” project knows about the “Tests” project, but the actual project dependency is the other way around.  It’s definitely better than using reflection to access private members for testing, but there are some definite pros and cons with this approach.

Pros

  • Allows your test libraries to access internal classes and methods for additional testing and coverage
  • Keeps your public API limited to what you want to publish
  • Provides greater flexibility for internal refactoring and backwards compatibility
  • Reduces the surface area of your public API

Cons

  • Easily abused, so things usually marked “private” are now marked “internal”
  • Potential loss of encapsulation
  • Decision about what should be public could be wrong
  • Essentially two levels of “public” visibility that have to be managed
  • Enforces bi-directional dependencies between assemblies

Personally, I always felt like marking something “internal” was cheating just a little bit, and I have trouble deciding when to make something internal or not.  But unless you’re delivering a public, published and documented API as part of your product, using the “InternalsVisibleTo” attribute would probably be overkill.

However, if you are delivering an API, you should consider using this attribute to keep a high level of coverage and reduce the surface area the API for your customers.  You could try starting by making everything “internal”, then shape the public API based on specific use cases.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://illuminatedcomputing.com/ Paul A Jungwirth

    Thank you for this post. Here are my reasons for unit testing with InternalsVisibleTo. I don’t really think it creates bi-directional dependencies. You can use it without listing your test assembly as a Reference, so production code still cannot see your test code. I do agree it’s unfortunate that it forces you to write private methods as internal.