BRO1312: Namespace names should begin with an upper-case letter¶
Every part of a namespace name is PascalCase: MyCompany.Billing, not myCompany.billing. Replaces StyleCop
SA1300 for namespaces (BRO1309 covers the other elements). Off by default: renaming a namespace
renames every type in it.
Example¶
root = true
[*.cs]
dotnet_diagnostic.BRO1312.severity = warning
Before¶
namespace myCompany.billing
{
internal class Invoice
{
}
}
namespace myCompany.web
{
using myCompany.billing;
internal class InvoicePage
{
public Invoice Current { get; } = new Invoice();
}
}
After¶
namespace MyCompany.Billing
{
internal class Invoice
{
}
}
namespace MyCompany.Web
{
using MyCompany.Billing;
internal class InvoicePage
{
public Invoice Current { get; } = new Invoice();
}
}
Why¶
Namespaces are PascalCase everywhere in .NET, and a lower-case part stands out in every using directive.
How the fix works¶
Like StyleCop, each part of every namespace declaration is reported. The fix renames the part everywhere in the
solution at once: every declaration (block and file-scoped), using directives of every kind (global using,
using static, aliases), qualified names (global:: included) and crefs. It's all or nothing: when one place can't be
renamed safely, nothing is.
Renaming a namespace changes the full name of every type in it. That's a breaking change for code outside the
solution, and for anything that stored a type name: Type.GetType("myCompany.billing.Invoice"), Json.NET's $type,
configuration files that name types. The fix leaves the namespace alone when a string in the solution or an
additional file (Razor, XAML) contains its name, but it can't see stored data or other repositories. Files and folders
aren't renamed (dotnet format only changes file contents).
Configuration¶
[*.cs]
# Parts that keep their casing, like StyleCop's allowedNamespaceComponents.
stylebro_allowed_namespace_components = eBay, iOS
stylebro_rename_public_api = true also renames names other assemblies see (default false, see Not reported; the owner's decision in decisions.md).
Not reported¶
- Where IDE1006 is suppressed: after
#pragma warning disable IDE1006(up to itsrestore), or with[SuppressMessage("Style", "IDE1006")]on the declaration, its member or type, or a global one targeting them. Code that opts out of the SDK's naming rules (a file copied from another project) keeps its names. - A new name your SDK naming rule rejects: when the first
dotnet_naming_rulethat covers the symbol is enforced (IDE1006, or the rule's own severity, at suggestion or above) and asks for another style, like_camelCasefor private properties, the name stays (renaming it would only trade this warning for IDE1006). - Public API (unless
stylebro_rename_public_api = true): Namespaces that hold such a type (directly or in a namespace inside them) that other assemblies see, that is public, protected or protected internal in types that are visible too. Renaming them breaks code outside the solution. Internal code is renamed, also withInternalsVisibleTo. - Allowed components (
stylebro_allowed_namespace_components): brand names likeiText,iOS,eBay. - The project's root namespace or a part of it (
RootNamespace, by default the project name). Embedded resource names start with the root namespace, not with the declared one, soGetManifestResourceStream(typeof(T).Namespace + ".data.json")would stop finding its resource, and new files and regenerated designer files would get the old casing again. Rename the project (or setRootNamespace) first; the declarations then follow on the next run. - A namespace another assembly also declares, inside it included (a package's
myCompany.commonnext to yourmyCompany.data): the other assembly keeps its name. A namespace that two projects of the solution share is reported in the project that doesn't see the other's part, and the fix renames both. - A namespace declared in generated code (
.designer.cs,.g.cs,<auto-generated>): the generator writes it again. - The new name already exists in the containing namespace (
MyCompanynext tomyCompany, or a type namedBilling).
Reported but not fixed¶
If dotnet format leaves a finding, StyleBro kept it on purpose. The fix looks at the whole solution, other
projects included, which the analyzer can't see, and leaves a change that would break something there: the name in a
string or a nameof (reflection, serialization), a member that would hide it, a use in generated code. It offers no
code action for such a finding, and stylebro-migrate format lists each one with its reason
(Findings kept on purpose); its --verify-no-changes doesn't fail on
them. Change it by hand only after checking those uses, or suppress it or record it in the baseline.
- The full name appears in a string anywhere in the solution, or in an additional file.
- The part appears in disabled
#ifcode. - A reference is in generated code, like a Razor component's
@using. - Another project gets part of the namespace from a library outside the solution.
- The new name already means something: in another project's containing namespace, where a reference looks the part up by its simple name, or for code inside the containing namespace that uses the new name for a type or alias (it would find the renamed namespace first).
Rename these by hand, or suppress the warning.
Compared with StyleCop¶
Same positions as StyleCop, minus the cases under "Not reported" (StyleCop has no such skips; its
allowedNamespaceComponents is stylebro_allowed_namespace_components, and stylebro-migrate carries it over).
StyleCop's fix renames only the one declaration it's on, which leaves every other file's
declarations and using directives behind (the code doesn't compile until all are renamed).