Addressing the CA1515 warning in .NET 9

January 3rd 2025 Static Analysis C#

In one of my hobby projects, I have all the code analysis rules enabled and treat all warnings as errors. As I tried to build it with .NET SDK 9 for the first time, it failed with many CA1515 errors:

Consider making public types internal

It took me a while to bring my solution back into a fully working state without disabling any rules. My solution consists of two projects: a console application and an accompanying test project. The errors wanted me to make all types in both projects public

The solution for that was to add the InternalsVisibleTo attribute to the application project:

[assembly: InternalsVisibleTo("Ca1515Warnings.Tests")]

Since I was using AutoMocker for Moq as the mocking library in my test project, I also had to make the internals visible to it using the following two attributes:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo(
    "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
)]

However, making the types internal introduced new occurrences of CA1852 in the test project:

Seal internal types

Making the types sealed fixed the problem, but this made me curious why I didn't get any such errors in the application project. I found the explanation in the documentation for the error:

By default, this rule is disabled if the assembly being analyzed uses InternalsVisibleToAttribute to expose its internal symbols.

As documented, this can be configured through the .editorconfig file, so I added one to my application project with the following contents:

[*.{cs,vb}]
dotnet_code_quality.CA1852.ignore_internalsvisibleto = true

This caused the CA1852 errors to show up in my application project as well, so I also made those types sealed to fix them.

I reproduced the whole process in a minimal sample project which you can find in my GitHub repository. The only difference is that I'm not using any mocking library in my sample project, so I didn't have to add internalsVisibleTo attributes for Moq. You can follow the entire process of fixing the errors through individual commits. To simulate how switching to .NET 9 SDK introduced the errors, I added a global.json file to the first commit to make sure .NET 8 SDK is used even when .NET 9 SDK is installed:

{  
  "sdk": {  
    "version": "8.0.404",  
    "rollForward": "latestFeature"  
  }  
}

Of course, you have to have .NET 8 SDK installed for this to work.

I wouldn't necessarily recommend having all the code analysis rules enabled in projects since not every rule makes enough sense for every project to justify the overhead of fixing the code. However, doing that can be an interesting learning experience, especially if you take the time to read the reasoning behind each of the rules you encounter.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License