Skip to content

sm new module: name-singular collision when module name equals its singular form (e.g. PageBuilder) #148

@antosubash

Description

@antosubash

Summary

sm new module <Name> produces an entity type whose name equals the module name when the singular form of <Name> equals <Name> itself (e.g. PageBuilder, Marketplace, Map). The generated code then has the entity type collide with the namespace, and the project fails to compile out of the box.

Repro

dotnet tool install -g SimpleModule.Cli   # 0.0.36
sm new project Repro
cd Repro
sm new module PageBuilder
dotnet build

Expected

Module compiles cleanly. The generator either:

  • Picks a different entity name when the singular collides with the module name (e.g. PageBuilderItem, or singularize-then-suffix), or
  • Uses an --entity <Name> flag to let the user choose, or
  • Errors at scaffold time with a friendly message asking for a non-colliding entity name.

Actual

3 build errors:

PageBuilderService.cs(8,35): error CS0118: 'PageBuilder' is a namespace but is used like a type
PageBuilderDbContext.cs(13,18): error CS0118: 'PageBuilder' is a namespace but is used like a type
PageBuilderService.cs(6,60): error CS0738: 'PageBuilderService' does not implement interface member 'IPageBuilderContracts.GetAllPageBuilderAsync()'. Cannot implement because of mismatched return type Task<IEnumerable<PageBuilder>>.

The generated files declare class PageBuilder inside namespace SimpleModule.PageBuilder.Contracts — and reference PageBuilder (the type) from sibling namespace SimpleModule.PageBuilder. Resolution picks the namespace, not the type, so PageBuilder in IEnumerable<PageBuilder> and DbSet<PageBuilder> won't compile.

Generated files involved

  • src/modules/PageBuilder/src/PageBuilder.Contracts/PageBuilder.cspublic class PageBuilder
  • src/modules/PageBuilder/src/PageBuilder.Contracts/IPageBuilderContracts.csTask<IEnumerable<PageBuilder>>
  • src/modules/PageBuilder/src/PageBuilder/PageBuilderDbContext.csDbSet<PageBuilder>
  • src/modules/PageBuilder/src/PageBuilder/PageBuilderService.csIEnumerable<PageBuilder>

Code path: ModuleTemplates.GetSingularName("PageBuilder") returns "PageBuilder" (no -s/-es to strip); the templates then use that singular as both the entity class name and as a member name, where it collides with the <Name> namespace.

Environment

  • sm --version: 0.0.36
  • dotnet --version: 10.0.201
  • macOS (Darwin 25.4.0)

Suggestion

When singularName == moduleName, suffix the entity (e.g. ${moduleName}Entity or ${moduleName}Record) or add a --entity <Name> flag to sm new module that overrides the inferred entity name. The flag form is most flexible — and analogous to how sm new feature would benefit too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions