LFZ.Templates 1.0.0

dotnet new install LFZ.Templates@1.0.0
                    
This package contains a .NET Template Package you can call from the shell/command line.

LFZ.Templates

A .NET 8 starter template for Lagos Free Zone services. Generates a five-project solution wired with Clean Architecture, CQRS, MediatR, FluentValidation, EF Core 8 (SQL Server), and a Blazor WebAssembly PWA frontend — installable from the dotnet CLI and discoverable in the Visual Studio "New Project" dialog.

LFZ = Lagos Free Zone. This package is the canonical scaffold used by Lagos Free Zone engineering for new line-of-business services and internal tools, so every new app starts from the same architectural baseline.


What you get

Running the template scaffolds a complete solution with five projects following the onion / Clean Architecture dependency rule:

Project Responsibility
<Name>.Domain Entities, value objects, domain events. Pure C#, no framework dependencies.
<Name>.Application CQRS commands, queries, handlers, validators, MediatR pipeline behaviors.
<Name>.Infrastructure EF Core ApplicationDbContext, entity configurations, external I/O.
<Name>.API ASP.NET Core Web API. Controllers, Swagger, exception-handling middleware.
<Name>.UI Blazor WebAssembly PWA. Calls the API over HTTP.

Solution file is <Name>.UI.slnx (SLNX format). All projects target net8.0.

Wired and ready

  • MediatR 14.1.0 with a pipeline of UnhandledExceptionBehavior → ValidationBehavior → LoggingBehavior around every handler.
  • FluentValidation 12.1.1 auto-discovered from the Application assembly; failures become HTTP 400 ValidationProblemDetails via API middleware.
  • EF Core 8.0.11 / SqlServer. ApplicationDbContext implements an IApplicationDbContext abstraction so Application code never depends on a concrete DbContext.
  • Swashbuckle 6.6.2 Swagger UI in Development.
  • Exception → HTTP mapping via ExceptionHandlingMiddleware: ValidationException → 400, NotFoundException → 404, anything else → 500 (logged).
  • Blazor WASM PWA with a registered HttpClient, default layout, and nav.
  • Agent guide (CLAUDE.md) shipped alongside the solution describing layer conventions, the feature-addition recipe, and anti-patterns — renamed automatically to reference your project name.

Architecture at a glance

+----------+        +-----------------+        +-------------------+
| Domain   | <----  | Application     | <----  | Infrastructure    |
+----------+        +-----------------+        +-------------------+
                            ^                            ^
                            |                            |
                       +----+----+                       |
                       |   API   |  <--------------------+
                       +---------+
                            ^
                            | HTTP only
                            |
                        +-------+
                        |  UI   |  (Blazor WASM PWA)
                        +-------+

Dependencies point inward. The UI talks to the API over HTTP — no project reference.


Install

From any console:

dotnet new install LFZ.Templates

Or from a local .nupkg (development / internal feed):

dotnet new install ./LFZ.Templates.1.0.0.nupkg

Visual Studio 2022 (17.x) auto-discovers dotnet new templates — restart VS once after install and the template appears in File → New → Project, filterable under C# / Web / Cloud.


Use

From the CLI

dotnet new lfz-clean -n CustomerPortal -o ./CustomerPortal
cd CustomerPortal
dotnet build CustomerPortal.UI.slnx

The -n value is substituted for LFZ throughout the scaffold — file names, folder names, namespaces, project references, and the contents of CLAUDE.md are all rewritten. So dotnet new lfz-clean -n CustomerPortal produces:

CustomerPortal/
  CustomerPortal.UI.slnx
  CLAUDE.md
  CustomerPortal.Domain/
  CustomerPortal.Application/
  CustomerPortal.Infrastructure/
  CustomerPortal.API/
  CustomerPortal.UI/

From Visual Studio

  1. File → New → Project
  2. Search for LFZ Clean Architecture Solution
  3. Set the Project name (this is the value used to rename LFZ everywhere)
  4. Create

The "Project name" you type flows into the same sourceName substitution as the CLI's -n flag.


After scaffolding

  1. Set the connection string. Edit <Name>.API/appsettings.json → ConnectionStrings:DefaultConnection. Default points at LocalDB with a database name derived from your project name. For non-local secrets, use User Secrets or environment variables rather than committing credentials.

  2. Create the database. From the solution root:

    dotnet ef migrations add InitialCreate --project <Name>.Infrastructure --startup-project <Name>.API
    dotnet ef database update --project <Name>.Infrastructure --startup-project <Name>.API
    
  3. Run the API.

    dotnet run --project <Name>.API
    

    Swagger is served at /swagger in Development.

  4. Run the UI.

    dotnet run --project <Name>.UI
    

    Update <Name>.UI/Program.cs so the HttpClient BaseAddress points at the API URL — by default it uses the WASM host's base address.


Adding a feature (vertical slice)

The template ships with a documented recipe in CLAUDE.md. Summary for a "Customer" feature:

  1. Domain → <Name>.Domain/Customers/Customer.cs inheriting BaseEntity.
  2. Application interface → add DbSet<Customer> Customers { get; } to IApplicationDbContext.
  3. Infrastructure → add DbSet<Customer> to ApplicationDbContext; add a CustomerConfiguration : IEntityTypeConfiguration<Customer> under Persistence/Configurations/.
  4. Migration → dotnet ef migrations add AddCustomer ... && dotnet ef database update ...
  5. Application handlers under <Name>.Application/Features/Customers/:
    • Commands/CreateCustomer/ -- command, handler, validator
    • Queries/GetCustomerById/ -- query, handler, DTO
  6. API → <Name>.API/Controllers/CustomersController.cs injecting IMediator.
  7. UI (optional) → Blazor page calling api/customers.

Validators are picked up automatically. Application handlers never return EF entities to callers — use DTOs.


What stays unchanged in the template

  • Inward-only dependency rule (Domain has zero project references).
  • Pipeline behavior order (UnhandledException → Validation → Logging).
  • API controllers stay thin (HTTP → IMediator.Send → result). Business rules live in handlers.
  • Persistence is accessed only through IApplicationDbContext from Application code.

Anti-patterns explicitly called out in CLAUDE.md include: referencing EF Core from Domain, returning entities from controllers, injecting handlers directly instead of IMediator, catching ValidationException/NotFoundException in handlers, and bypassing FluentValidation with manual checks.


Known gaps

The scaffold includes wiring points that are intentionally left for the consumer to complete:

  • IAuditableEntity exists; no SaveChanges interceptor populates CreatedAt/CreatedBy yet.
  • IDomainEvent collection exists on BaseEntity; no dispatcher publishes events via IMediator.Publish yet.
  • No authentication / authorization scheme is configured (UseAuthorization() is called, but no auth pipeline).
  • No CORS policy between the WASM UI and API.
  • Template scaffolding (WeatherForecastController, WeatherForecast.cs, Weather.razor) is shipped as a working sample — remove when real features land.
  • No test projects in the solution.

Uninstall

dotnet new uninstall LFZ.Templates

To list every installed template package: dotnet new uninstall (no args).


Template parameters

Parameter Description Default
-n, --name Project name. Substitutes LFZ throughout the scaffold. (required)
-o, --output Output directory. ./

Versioning

  • 1.0.0 -- Initial release. .NET 8, Clean Architecture, CQRS, MediatR 14.x, Blazor WASM.

Maintainer

Lagos Free Zone Engineering.

  • 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.

Version Downloads Last Updated
1.0.0 282 5/25/2026