Skip to content

Namespace Roots

A namespace root pins a namespace as the base of the output folder hierarchy and places its output under a named base folder. When a type’s namespace begins with a configured root, the root prefix is stripped and the remainder is placed under the specified folder.

This is an alternative to CratisProxiesSegmentsToSkip that works by name rather than by a fixed segment count, making it more resilient when namespace depths vary across a project.

<ItemGroup>
<NamespaceRoot Namespace="MyApp.Features" Folder="features" />
</ItemGroup>
AttributeDescription
NamespaceThe C# namespace prefix to match
FolderThe output sub-folder to place matching types under

Example: With namespace root MyApp.Featuresfeatures:

C# namespaceOutput folder
MyApp.Features.Auth.Registrationfeatures/Auth/Registration/
MyApp.Features.Billing.Invoicesfeatures/Billing/Invoices/
MyApp.Features.Authfeatures/Auth/
MyApp.Featuresfeatures/
MyApp.Other(falls back to segment-skip logic — namespace root does not apply)

You can declare multiple roots. The longest matching namespace wins:

<ItemGroup>
<NamespaceRoot Namespace="MyApp.Features" Folder="features" />
<NamespaceRoot Namespace="MyApp.SharedTypes" Folder="shared" />
</ItemGroup>

Namespace roots only take effect for types whose namespace matches the root. Types that do not match any configured root fall back to CratisProxiesSegmentsToSkip as normal.

Pass one or more --namespace-root flags using = to separate the namespace from the folder:

Terminal window
proxygenerator assembly.dll output-path \
--namespace-root=MyApp.Features=features \
--namespace-root=MyApp.SharedTypes=shared