A Roslyn analyzer is a class that derives from DiagnosticAnalyzer, carries a DiagnosticAnalyzer attribute naming its language, registers actions in Initialize, and reports diagnostics when code matches. Package it as NuGet so it applies per project, then set its severity in an EditorConfig file.
What Microsoft's tutorial shows
Microsoft's analyzer tutorial builds a "Make Const" analyzer with a code fix, starting from the Analyzer with Code Fix template in Visual Studio. It states that every diagnostic analyzer must provide the attribute describing the language it works on and must derive, directly or indirectly, from DiagnosticAnalyzer. Actions are registered in your override of Initialize, and the tutorial changes the registration to a syntax node action for local declaration statements.
You need the .NET Compiler Platform SDK installed through the Visual Studio Installer, where it is an optional component.
Steps
- Create the project from the analyzer template.
- Define the diagnostic: an id, a title, a message format and a default severity.
- In Initialize, register an action for the syntax kind you care about.
- In the action, inspect the node and call ReportDiagnostic when it matches.
- Optionally add a code fix so developers can accept a recommendation in one step.
- Write unit tests with sample code that should and should not be flagged. The tutorial finishes by improving the analysis through unit tests.
- Package it and add it to the projects that need it.
Installing and scoping
Microsoft's documentation describes NuGet as the preferred way to install an external analyzer. A NuGet analyzer applies only to the project where it is installed, while an analyzer installed as a Visual Studio extension applies to any solution you open. For a team rule, choose NuGet so the rule travels with the repository and runs in CI as well as in the editor.
Severity levels
Each analyzer rule has a default severity that you can customize. The documented levels are Error, Warning, Suggestion, Silent, None and Default. In an EditorConfig file the syntax is dotnet_diagnostic followed by the rule id and severity, for example setting a rule id to error under a section for C# files. Because the setting lives in a file in the repository, severity changes are code reviewed.
| Severity | Typical use for a new custom check |
|---|---|
| Suggestion | First rollout, visible in the editor only |
| Warning | Shows in builds, does not fail them |
| Error | Fails the build once existing violations are fixed |
| None | Turned off while you investigate noise |
Practical advice
- Keep one diagnostic per concern. A single analyzer that reports five different things is hard to tune.
- Give each diagnostic a help link to a short internal page that explains the problem and the fix.
- Test on real project code before raising severity, since sample tests rarely cover every coding style.
Quick check
Do I need a code fix?
No. A code fix is optional. It helps adoption when the safe replacement is mechanical, but an analyzer is valid without one.
Where should the severity setting live?
In an EditorConfig file in the repository, so changes are reviewed and apply to every developer and to CI.
Safeguard's scanning covers dependencies and SBOMs, and its reachability analysis helps show which findings your code can actually call. You can run a free scan on a repository.
Sources
- Microsoft Learn: Write your first analyzer and code fix
- Microsoft Learn: Roslyn analyzers overview
- Microsoft Learn: Use Roslyn analyzers
Last reviewed: 19 October 2026.