Digitals.Analyzers 0.7.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Digitals.Analyzers --version 0.7.2
                    
NuGet\Install-Package Digitals.Analyzers -Version 0.7.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Digitals.Analyzers" Version="0.7.2">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Digitals.Analyzers" Version="0.7.2" />
                    
Directory.Packages.props
<PackageReference Include="Digitals.Analyzers">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Digitals.Analyzers --version 0.7.2
                    
#r "nuget: Digitals.Analyzers, 0.7.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Digitals.Analyzers@0.7.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Digitals.Analyzers&version=0.7.2
                    
Install as a Cake Addin
#tool nuget:?package=Digitals.Analyzers&version=0.7.2
                    
Install as a Cake Tool

Digitals.Analyzers

One package that brings the Digitals C# analyzer set and the shared severity policy to a .NET repo. Reference it instead of wiring up four analyzer packages and copying an .editorconfig between repos.

This package covers production code. Test projects are covered by its companion, Digitals.Testing, which brings the test stack, the test severity policy and a coverage gate. Nothing test-specific lives here.

Install

<PackageReference Include="Digitals.Analyzers" PrivateAssets="all" />

Put it once in Directory.Build.props so it covers every project, and delete any existing references to the analyzer packages listed below — duplicates cause version conflicts.

The package is marked DevelopmentDependency, so PrivateAssets="all" is what NuGet applies by default anyway. It stops the analyzers flowing on to your consumers.

Set these alongside it, in the same Directory.Build.props:

<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors>nullable</WarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

The first two are enforced: the package fails the build with DIGB002 when Nullable is not enable and DIGB003 when TreatWarningsAsErrors is not true, because without them the whole severity policy is advisory. A project mid-migration can opt out explicitly, next to a comment saying why:

<DigitalsAllowNullableDisabled>true</DigitalsAllowNullableDisabled>
<DigitalsAllowWarningsNotAsErrors>true</DigitalsAllowWarningsNotAsErrors>

WarningsAsErrors=nullable keeps nullable-flow warnings as errors even if warnings are later relaxed via WarningsNotAsErrors. Without EnforceCodeStyleInBuild the IDExxxx rules never fire in dotnet build — they stay IDE-only. GenerateDocumentationFile is what makes IDE0005 (unused usings) run in a build.

Migrating an existing repo, including how to stage the noise: docs/ADOPTION.md.

What you get

Analyzer package Rules
SonarAnalyzer.CSharp Quality and bug rules (S####)
Roslynator.Analyzers Refactoring and idiom rules (RCS####)
Roslynator.Formatting.Analyzers Formatting rules (RCS0###)
Microsoft.VisualStudio.Threading.Analyzers Async and threading rules (VSTHRD###)
Microsoft.CodeAnalysis.BannedApiAnalyzers Enforces the banned-API list (RS0030)

Plus configuration that is injected automatically — nothing to import:

  • Severity policy for the packs above, plus the naming rules, applied at global_level 100.
  • Banned APIs (RS0030) — the ambient clock: DateTime.Now, DateTime.UtcNow, DateTime.Today, DateTimeOffset.Now, DateTimeOffset.UtcNow. Inject TimeProvider instead: TimeProvider.System in your composition root, FakeTimeProvider in tests.
  • Banned packages (DIGB001, a build error) — see the table below.
  • Custom rules (DT#####) — see the table below.

Some rules that ship disabled or info-only are escalated to warning: SYSLIB1045 (use [GeneratedRegex]), CA2254 (no interpolation in log message templates), VSTHRD100 (no async void), CA1707 (no underscores in identifiers), S6513 ([ExcludeFromCodeCoverage] must carry a Justification), CA1851 (an IEnumerable enumerated more than once), CA1310 (locale-dependent string comparison), CA1069 (duplicated enum values), S3776 (cognitive complexity over 15), CA5404/CA5405 (token validation disabled or always skipped), CA5390/CA5403 (hard-coded key or certificate), CA2248 (Enum.HasFlag with the wrong enum type), RCS1157 (a [Flags] composite covering an undefined bit), IDE0072/IDE0010 (a switch over an enum must name every member even when it has a default/_ arm — otherwise the discard silently swallows members added later; the compiler's own CS8509 only fires when there is no default arm). Others are set to suggestion so they show in the IDE without failing a build: CA2100 (raw SQL), CA1002/CA1819 (read-only collection properties), CA1021 (no out parameters), S109 (magic numbers), CA1515 (public types in an app project could be internal), RCS1079 (throws NotImplementedException).

Everything ships as warning, never error. Your repo decides how hard that bites via TreatWarningsAsErrors — which is why the package insists on it. The exceptions are the DIGB00x build errors: DIGB001 (banned package), DIGB002 (Nullable not enable), DIGB003 (TreatWarningsAsErrors not true).

Custom rules

ID Rule Do this instead
DT00001 Any use of System.DateTime, including bare declarations like DateTime Foo { get; set; } DateOnly for a calendar date, TimeOnly for a time of day, TimeSpan for a duration, DateTimeOffset in UTC for an instant. DateTime is an interop-boundary exception
DT00002 DateTimeOffset.LocalDateTime / .DateTime — both quietly hand back a DateTime .UtcDateTime, the sanctioned boundary conversion
DT00003 new HttpClient() IHttpClientFactory via AddHttpClient — a client per call exhausts sockets
DT00004 dynamic Resolve the type at compile time: generics, DI, or a typed model
DT00006 double/float whose name looks like money (price, cost, fee, …). suggestion, IDE-only decimal
DT00007 A class deriving from System.TimeProvider FakeTimeProvider from Microsoft.Extensions.TimeProvider.Testing in tests, TimeProvider.System in production. Deriving from the real FakeTimeProvider to add helpers is fine
DT00008 A method whose return type is a nullable collection — IReadOnlyCollection<string>? GetOrders(), Task<List<Order>?>, T[]?, IAsyncEnumerable<T>? Return an empty collection: [], Array.Empty<T>(), ImmutableArray<T>.Empty. null and empty are the same answer to a caller, so the ? only buys a guard at every call site. string? is untouched, and so are properties and fields

These carry their own IDs rather than reusing RS0030 on purpose: a #pragma disabling an interop DateTime at a boundary must not also switch off the ambient-clock ban in the same region.

Banned packages

A direct PackageReference to any of these fails the build with DIGB001. Transitive dependencies are not checked. Test frameworks, assertion and mocking libraries are banned by Digitals.Testing instead, under DIGT002.

Instead of Use
Newtonsoft.Json, Microsoft.AspNetCore.Mvc.NewtonsoftJson System.Text.Json
AutoMapper and its DI extension Explicit mapping code (v15+ needs a commercial licence)
EntityFramework Microsoft.EntityFrameworkCore
System.Data.SqlClient Microsoft.Data.SqlClient
Microsoft.EntityFrameworkCore.Proxies Explicit loading — no lazy loading

If you genuinely need one, allow it explicitly with a comment saying why:

<DigitalsAllowBannedPackages>Newtonsoft.Json</DigitalsAllowBannedPackages>

Turning something off

A whole rule, repo-wide. A repo-local .editorconfig always beats the packaged policy. This is the supported opt-out, not a workaround:

[*.cs]
dotnet_diagnostic.S1234.severity = none

One line. Legitimate exceptions exist — bootstrap logging before DI is built, EF migration defaults:

#pragma warning disable RS0030 // Serilog bootstrap, DI not built yet
Log.Information("Starting at {Now}", DateTimeOffset.UtcNow);
#pragma warning restore RS0030

Suppressions are greppable and show up in review. If they multiply in one area, that is worth a conversation rather than more pragmas.

What your repo still needs

A global config can only carry severities, so editor behaviour stays in your own .editorconfig:

root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true

[*.{props,csproj}]
indent_style = tab
indent_size = 4
tab_width = 4

[*.{cs,vb,cshtml}]
indent_style = tab
indent_size = 4
tab_width = 4
max_line_length = 120

Any path-scoped exceptions live there too ([**/Pages/**.cshtml.cs], [**/Migrations/**.cs]) — a global config has no path sections.

Notes

C# only in practice. Sonar C# and Roslynator are C#-only; the threading and banned-API analyzers also cover VB. In an F# project the package does nothing.

One version to review. Bumping any bundled analyzer means a new version of this package, so an upgrade is a single version bump and a single changelog to read across every repo.

Versions come from git tags via MinVer and follow SemVer. Release notes: Releases.

License

MIT — see LICENSE. This covers the code in this repository: the config files, the banned-package check and the custom DT##### analyzer. The bundled third-party analyzers keep their own licences and reach you as ordinary NuGet dependencies.

Working on the package itself: docs/MAINTAINING.md.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.10.3 71 9/29/2026
0.10.2 109 9/29/2026
0.10.1 236 9/23/2026
0.10.0 88 9/23/2026
0.9.0 95 9/23/2026
0.8.0 134 9/21/2026
0.7.2 109 9/19/2026
0.7.1 91 9/19/2026
0.7.0 88 9/19/2026
0.6.0 471 8/31/2026
0.5.1 260 8/26/2026
0.5.0 148 8/20/2026