Roslyn analyzers for solution in .NET

Are you using Roslyn analyzers in your solution? Off cource you use it, even if you don’t know about it. Long story short, Roslyn analyzer is static code analysis with possible refactorings (like eslint/prettier in JS world) All Visual Studio refactoring is based on Roslyn analyzers. It is really cool, beacuse you could inspect C# code with C# code. More about roslyn analyzers here: https://github.com/dotnet/roslyn-analyzers.

Today my colleague called me, that he has problem with adding Roslyn analyzers for whole solution. (This one, that punch you if you dont add Async suffix to async method) Just use Directory.Build.props Directory.Build.targetsand thats it, I told him. Problem was, that Visual Studio is not really friendly to Directory.Build.props and Directory.Build.targets and in combination with analyzers you are reliant only on dotnet CLI (yes I hate you VS for locking files, but I have secret weapon on you).

So, how does it exacly work? Directory.Build.props is used before all .csproj project in folder structure below.

So, our solution (.sln) file is not hardwired with Directory.Build.props. Solution file is “agnostic” to build system and have knowledge just about project that could be build. Even if you add Directory.Build.props to solution as solution item, msbuild ignore it, if in folder structure below isnt any csproj. But best practice is have all your csprojs below your solution file.

Here is created sample solution https://github.com/PadreSVK/dotnet-solution-analyzers-sample. It contains 2 branches master and fixed-code. Master has some “issues” so it can’t be builded.

C:.
   Directory.Build.props       // Build props for projects (ClassLibrary1, ConsoleApp1, ConsoleApp2)
   Solution.ruleset            // our rules set - you could modify rules severity 
   SolutionAnalyzersCore.sln

├───ClassLibrary1
       Class1.cs
       ClassLibrary1.csproj

├───ConsoleApp1
       ConsoleApp1.csproj
       Program.cs

└───ConsoleApp2
        ConsoleApp2.csproj
        Program.cs

Now structure of Directory.Build.props:

Syntax is the same as csproj, so you can use <PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="16.5.132" /> like in csproj. Just package from nuget and run dotnet build. Everything automagicaly works 🐱‍🏍. Now you can run Visual Studio and enjoy analyzers :3

analyzers in action

Here is list of analyzers in Microsoft.VisualStudio.Threading.Analyzers. At the end just one more thing - if you want to use async Task Main method, you must “bypass” analyzer rule by pragma warning directive like in example below.

And thats it! 😎