MagicCSharp.Analyzers 1.0.2

dotnet add package MagicCSharp.Analyzers --version 1.0.2
                    
NuGet\Install-Package MagicCSharp.Analyzers -Version 1.0.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="MagicCSharp.Analyzers" Version="1.0.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="MagicCSharp.Analyzers" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="MagicCSharp.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 MagicCSharp.Analyzers --version 1.0.2
                    
#r "nuget: MagicCSharp.Analyzers, 1.0.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 MagicCSharp.Analyzers@1.0.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=MagicCSharp.Analyzers&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=MagicCSharp.Analyzers&version=1.0.2
                    
Install as a Cake Tool

MagicCSharp.Analyzers

The code-style conventions of a MagicCSharp codebase, as compile errors. Add it when a review comment keeps coming back — "inject the clock", "name it after its type", "that should be a record" — and you would rather the build said it, once, to everyone, before the pull request exists.

Every rule is on and an error by default, in tests too. Each is a Roslyn analyzer, so it shows in the IDE as you type and fails dotnet build in CI; there is no separate lint step to forget.

dotnet add package MagicCSharp.Analyzers

A repository created with mcs init already references it from Directory.Build.props, so every project gets it. The package is a development dependency: it adds nothing to your assemblies, and a project that references yours does not inherit the rules.

The rules

Rule What it enforces
MCS0001 Records declare members in a body, not a positional parameter list
MCS0002 At most 4 parameters per method; group related ones into a request record (controller actions and AI tool methods marked [Description] are exempt)
MCS0003 Null checks are == null / != null, not is null / is not null
MCS0004 No property patterns (x is Order { Total: > 0 }); write the checks out
MCS0005 No patterns that declare a variable (x is Order order); cast on its own line
MCS0006 Braces on every control-flow body (else if chains and stacked usings are fine)
MCS0007 A constructor or [FromServices] dependency on one of your own interfaces is named after it: IGetOrderUseCase getOrder, never useCase
MCS0008 No DateTime.Now, UtcNow or Today, or DateTimeOffset.Now or UtcNow; inject TimeProvider
MCS0009 Methods and local functions have block bodies; expression-bodied properties are fine
MCS0010 No cryptic abbreviations (repo, ctx, svc, req, tmp, obj, …)
MCS0011 Booleans start with is/has/can/should/allow/was/will/must/are
MCS0012 A type's suffix matches what it implements: …UseCase for IMagicUseCase, …Repository for a repository interface
MCS0013 Extra public types in a file support the one it is named for — its interface, request, result, enum, or a type it uses
MCS0014 A file is named after a type it declares (Program.cs, static classes and enum-only files are exempt)
MCS0015 A read-only use case (Get…, List…, Search…) does not log the Executing: trace line
MCS0017 No mutable static state: static fields are readonly or const, static properties have no setter
MCS0018 File-scoped namespaces
MCS0019 A variable holding one of your own types, from new or foreach, is named after the type: var orderEdit = new OrderEdit()
MCS0020 Infrastructure dependencies have one name each: timeProvider, keyGenService, eventDispatcher, distributedLockProvider, logger
MCS0021 DbSet properties are plural
MCS0022 Types ending in Request, Result, Payload or Event are records, not classes

MCS0016 is deliberately unused, so the numbers match the rule set these came from.

"Your own" types, for MCS0007, MCS0012 and MCS0019, are the ones declared in the project being built, in any assembly whose name starts with the same first segment — Acme.Shop.Domains.Orders and Acme.Libraries.Events are one codebase — and in MagicCSharp's own packages. Third-party types are left alone; you do not choose their names.

Members whose name is dictated by something else — an override, an interface implementation, a parameter of an AI tool method — are skipped by the naming rules. To rename a property that is part of a contract, add the new one and keep the old one marked [Obsolete], forwarding to it; obsolete members are skipped too.

Changing a rule

Every rule is configured in .editorconfig, like any other analyzer:

[*.cs]
# A warning rather than an error
dotnet_diagnostic.MCS0002.severity = warning

# Off entirely
dotnet_diagnostic.MCS0015.severity = none

# Off for one folder
[tests/**/*.cs]
dotnet_diagnostic.MCS0019.severity = none

For one line, suppress it where it happens and say why:

#pragma warning disable MCS0008 // an event records when it happened, and has no provider to ask
public DateTimeOffset OccurredOn { get; init; } = DateTimeOffset.UtcNow;
#pragma warning restore MCS0008

To take them all out of one project, drop the reference there — in a repository from mcs init, where Directory.Build.props adds it:

<ItemGroup>
    <PackageReference Remove="MagicCSharp.Analyzers" />
</ItemGroup>

Generated code

Generated code is not analyzed: anything with an <auto-generated> header, *.g.cs and *.designer.cs files, and whatever .editorconfig marks as generated_code. An Entity Framework migration's main file has no header, so mark migrations there — mcs init writes this for you:

[**/Migrations/*.cs]
generated_code = true
  • MagicCSharp.Cli — mcs init adds these rules to a new repository; mcs validate lints the conventions an analyzer cannot see
  • MagicCSharp — the use cases, key generation and events the naming rules know about

The whole picture, and the optional repository layout: github.com/MagicDoorInc/MagicCSharp. MIT.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

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
1.0.2 345 9/24/2026
1.0.1 79 9/24/2026