Yash.CleanArchitecture.Templates
1.2.1
dotnet new install Yash.CleanArchitecture.Templates@1.2.1
Clean Architecture .NET Web API Template
A dotnet new template that scaffolds a Clean Architecture solution:
ProjectName.sln
src/
ProjectName.Domain entities (Order, User), enums, no dependencies
ProjectName.Application service layer (IOrderService/OrderService, IUserService/IAuthService),
IRepository<T>, IRepositoryFactory, IUnitOfWork, DTOs, FluentValidation
ProjectName.Infrastructure EF Core, Repository<T>, RepositoryFactory, UnitOfWork, JWT token service
ProjectName.WebApi controllers, Program.cs, DI composition root
ProjectName is the placeholder (sourceName in template.json). Running
dotnet new cleanwebapi -n InventoryApi renames every folder, namespace, file,
.csproj, and .sln reference to InventoryApi.*.
Architecture pattern
- Service layer, not CQRS/MediatR:
IOrderService/OrderService,IUserService/UserService,IAuthService/AuthService. IRepositoryFactoryresolvesIRepository<T>per entity. Kept separate fromIUnitOfWorkon purpose, services only depend on what they actually need.IUnitOfWorkowns only the transaction boundary:SaveChangesAsyncandExecuteAsync(...), which wraps a block of repository calls in a real DB transaction (EF Core execution strategy, safe with retry-on-failure providers).Repository<T>gives generic CRUD (GetByIdAsync,GetAllAsync,FindAsync,Query(),AddAsync,Update,Remove) per entity.
Optional features (template parameters)
| Parameter | Values | Default | What it controls |
|---|---|---|---|
--UseJwt |
true / false |
true |
JWT auth end-to-end: User entity, IUserService/IAuthService, AuthController (/api/auth/register, /api/auth/login), UsersController, IJwtTokenService, PBKDF2 password hashing, Swagger "Authorize" button, [Authorize] on OrdersController. When false, none of these files are generated at all, and Program.cs/.csproj drop the JWT wiring and package refs entirely. |
--DbProvider |
SqlServer / PostgreSQL / MySQL |
SqlServer |
Which EF Core provider package and Use___() call gets included. Only the matching NuGet package reference survives in Infrastructure.csproj. |
--Framework |
net8.0 / net9.0 |
net8.0 |
Target framework across all .csproj files. |
--IncludeAngularClient |
true / false |
true |
Includes an Angular 18 standalone client app under clientapp/ (routing, a reactive form, an HttpClient service wired to /api/orders). When false, the entire clientapp/ folder is omitted, no .csproj/.sln changes either way since it's not a VS project. |
appsettings.json includes commented example connection-string formats for all
three providers under _ConnectionStringExamples_ChangeFormatPerProvider — copy
the one matching your --DbProvider choice into ConnectionStrings:DefaultConnection
after generating, and set a real Jwt:Key if UseJwt is on.
Folder layout of this repo
clean-arch-template/
content/ <- becomes the template source
.template.config/template.json
ProjectName.sln
src/...
pack/
Yash.CleanArchitecture.Templates.csproj <- packs "content" into a .nupkg
README.md <- also shown on the nuget.org package page
1. Test the template locally (before publishing)
dotnet new install ./content
dotnet new list
dotnet new cleanwebapi -n InventoryApi --DbProvider PostgreSQL --UseJwt true -o ./InventoryApi
dotnet new uninstall ./content
2. Pack it as a NuGet package
cd pack
dotnet pack Yash.CleanArchitecture.Templates.csproj -c Release
# output: pack/nupkg/Yash.CleanArchitecture.Templates.<version>.nupkg
Sanity check before pushing: rename the .nupkg to .zip and confirm the path
inside is exactly content\.template.config\template.json — not
content\content\.template.config\.... This is controlled by the PackagePath
metadata on the Content item in the pack .csproj; do not add
ContentTargetFolders back, it double-prefixes the path and breaks generation
(an earlier version of this template hit exactly this bug).
3. Publish to NuGet.org
Either:
- CLI:
dotnet nuget push ./nupkg/<file>.nupkg --api-key <KEY> --source https://api.nuget.org/v3/index.json - Manual: nuget.org → your account → Upload Package → drag the
.nupkg
Package IDs and versions are immutable once pushed — bump PackageVersion in the
pack .csproj for every future update, you can't overwrite an existing version.
4. Use it anywhere
dotnet new install Yash.CleanArchitecture.Templates
dotnet new cleanwebapi -n InventoryApi -o ./InventoryApi
cd InventoryApi
dotnet restore
dotnet run --project src/InventoryApi.WebApi
Update / remove:
dotnet new update
dotnet new uninstall Yash.CleanArchitecture.Templates
Do not manually extract the .nupkg with Explorer/7-Zip and open the folder
in Visual Studio — that surfaces the raw package internals (_rels, package,
.signature, .nuspec) instead of a generated project, and the ProjectName
placeholder never gets renamed. Always go through dotnet new install +
dotnet new cleanwebapi.
Do not add it via "Manage NuGet Packages" in Visual Studio either — a
PackageType=Template package isn't a library dependency, VS will report
"package type 'Template' is not supported by project ...". Install it globally
via the CLI command above instead; recent VS versions then also surface it in
the New Project dialog automatically.
-
net8.0
- 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.