Skip to content
Β 
Β 

Latest commit

Β 

History

2,670 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Clean Architecture Blazor Server Application Template

Build CodeQL Docker Image CI

A production-ready Blazor Server application template built on Clean Architecture principles, offering advanced code generation, AI-assisted development workflows, and enterprise-grade capabilities for building scalable and maintainable systems.

🎯 Overview

This repository provides a production-grade Blazor Server solution template designed in strict accordance with Clean Architecture principles and modern enterprise application standards.

Built on .NET 10, the template demonstrates a well-structured, scalable, and maintainable architecture for developing complex business systems. It integrates advanced code generation capabilities, AI-assisted development workflows, and specification-driven design patterns, enabling teams to accelerate development while preserving architectural consistency and code quality.

The solution is intended to serve both as a reference implementation for Blazor Clean Architecture best practices and as a ready-to-use foundation for enterprise-level applications that require long-term maintainability, extensibility, and high development efficiency.

Key Features

  • πŸ—οΈ Clean Architecture: Strict layer separation with dependency inversion
  • 🎨 Modern UI: Beautiful, responsive interface built with MudBlazor
  • ⚑ Real-time Communication: SignalR integration for live updates
  • πŸ” Enterprise Security: Multi-factor authentication, role-based access control
  • 🌐 Multi-tenancy: Built-in tenant isolation and management
  • πŸ“Š Advanced Data Grid: Sorting, filtering, pagination, and export capabilities
  • 🎨 Code Generation: Visual Studio extension for rapid development
  • 🐳 Docker Ready: Complete containerization support
  • πŸ“± Progressive Web App: PWA capabilities for mobile experience

🌟 Live Showcase

Experience the application in action:

Application Demo

Live Demo: architecture.blazorserver.com

Featured Projects Built with This Template

HSE Management System HSE Management System - GitHub | Live Demo

Digital Product Passport EU Digital Product Passport - Live Demo

πŸ› οΈ Technology Stack

Layer Technologies
Frontend Blazor Server, MudBlazor, SignalR
Backend .NET 10, ASP.NET Core, MediatR, FluentValidation
Database Entity Framework Core, MSSQL/PostgreSQL/SQLite
Authentication ASP.NET Core Identity, OAuth 2.0, JWT
Caching FusionCache, Redis
Background Processing Hosted services, in-memory queues
Testing xUnit, FluentAssertions, Moq
DevOps Docker, GitHub Actions

πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Server.UI     β”‚    β”‚  Application    β”‚    β”‚     Domain      β”‚
β”‚   (Blazor)      │───▢│   (Business)    │───▢│   (Entities)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                        β”‚                        
         β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               
         └─────────────▢│ Infrastructure  β”‚               
                        β”‚   (Data/IO)     β”‚               
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               

Layer Responsibilities

  • Domain: Core business entities and rules (no dependencies)
  • Application: Business logic, interfaces, and DTOs
  • Infrastructure: External concerns (database, email, file system)
  • Server.UI: Blazor components and user interface

🧩 Dynamic Fields Architecture

The dynamic-fields subsystem adds template-driven attributes to selected business entities without adding entity-specific columns for every custom field. Product is the reference implementation, and the same building blocks can be reused by future entities such as Contract or Asset.

Model

FieldGroupTemplate
└── FieldSection
    └── FieldSectionItem ──> FieldDefinition
                               (type, label, limits, regex, unit, picklist)

ExtensibleEntity
└── FieldGroupInstance ──> FieldGroupTemplate
    └── FieldValue ──────> FieldDefinition

The model separates field metadata from record values:

  • FieldDefinition describes a reusable field and its validation metadata.
  • FieldGroupTemplate organizes definitions into ordered sections and determines which fields apply to a business record.
  • FieldGroupInstance binds one extensible business record to one template.
  • FieldValue stores one normalized string value for one definition.
  • ExtensibleEntity exposes the optional DynamicFields navigation used by supported business entities.

ExtensibleEntity uses EF Core table-per-type (TPT) mapping. FieldGroupInstance.Id is both its primary key and a foreign key to ExtensibleEntity.Id, which enforces at most one dynamic-field instance per business record while preserving normal EF navigation properties and referential integrity.

public abstract class ExtensibleEntity : BaseAuditableEntity
{
    public FieldGroupInstance? DynamicFields { get; set; }
}

public class Product : ExtensibleEntity
{
    // Product fields...
}

Layer Responsibilities and Data Flow

  1. The business module selects a trusted template code, such as ProductDynamicFields.DefaultTemplateCode.
  2. Application loads the complete template, including sections, items, and definitions.
  3. DynamicFieldsEditor renders the template and delegates each typed control to DynamicFieldInput.
  4. The command submits FieldValueDto values identified by FieldDefinitionId; submitted definition metadata and row IDs are not authoritative.
  5. FieldGroupInstanceSynchronizer validates the complete value set against the database-loaded template, normalizes values, and updates the owner's entity graph.
  6. The command handler saves fixed fields and dynamic fields in one SaveChangesAsync operation.

The reusable synchronizer does not select templates, query the database, start transactions, or save changes. Those responsibilities remain in the business command handler. It validates required fields, length and regex rules, numeric ranges, dates, Booleans, and single/multiple picklists before mutating the graph.

Supported values are stored in culture-independent formats:

Field type Stored representation
String Trimmed string or null
Integer Invariant integer string
Number Invariant decimal string
DateOnly yyyy-MM-dd
DateTime yyyy-MM-dd HH:mm:ss
Boolean true or false
Single picklist Selected option
Multiple picklist JSON string array

Extending Another Entity

Use the following steps to add dynamic fields to another business entity. Keep template selection inside that entity's Application feature; do not add entity-specific foreign keys or type switches to FieldGroupInstance.

  1. Inherit from ExtensibleEntity:

    public class Contract : ExtensibleEntity
    {
        public string ContractNumber { get; set; } = null!;
        public DateOnly EffectiveDate { get; set; }
    }
  2. Keep the entity's normal EF configuration and add a migration. The existing TPT and shared-primary-key configurations provide the dynamic-fields relationship.

  3. Define the module-owned template policy:

    public static class ContractDynamicFields
    {
        public const string DefaultTemplateCode = "contract-attributes";
    }
  4. Create or seed the corresponding FieldGroupTemplate, sections, items, and definitions through the existing management module.

  5. In create/update handlers, load the authoritative template and the owner's current dynamic values, then call the shared synchronizer before the handler's single save:

    var result = new FieldGroupInstanceSynchronizer()
        .Synchronize(contract, template, request.DynamicFieldValues);
    
    if (!result.Succeeded)
        return await Result<int>.FailureAsync(result.ErrorMessage);
    
    await context.SaveChangesAsync(cancellationToken);
  6. Reuse GetFieldGroupTemplateByCodeQuery, FieldValueDto, DynamicFieldsEditor, and DynamicFieldInput in the entity form. The reusable components contain no Product-specific template code.

  7. Add tests for create, update, required/invalid values, foreign or duplicate definition IDs, template mismatch, and atomic persistence.

For the complete design decisions and Product example, see Extensible Entity Dynamic Fields Design and Product Dynamic Fields Editor Design.

πŸ“‹ Development Workflow

The project includes a comprehensive Development Workflow with:

  • Task Management: Structured approach to feature development
  • Code Review Guidelines: Quality assurance processes
  • Testing Strategies: Unit and integration testing patterns
  • Deployment Procedures: CI/CD pipeline configurations

πŸš€ Quick Start

Prerequisites

Installation

  1. Install the Template

    dotnet new install CleanArchitecture.Blazor.Solution.Template
  2. Create New Project

    dotnet new ca-blazorserver-sln -n YourProjectName
    cd YourProjectName
  3. Setup Database

    dotnet ef database update --project src/Migrators/Migrators.MSSQL
  4. Run the Application

    dotnet run --project src/Server.UI
  5. Access the Application

    • Navigate to https://localhost:7152
    • Login with default credentials (see documentation)

🐳 Docker Deployment

Run with configured database provider (In-Memory removed):

docker run -p 8443:443 \
  -e DatabaseSettings__DBProvider=mssql \
  -e DatabaseSettings__ConnectionString="Server=127.0.0.1;Database=BlazorDashboardDb;User Id=sa;Password=<YourPassword>;MultipleActiveResultSets=true;Encrypt=false;TrustServerCertificate=false" \
  blazordevlab/cleanarchitectureblazorserver:latest

Production Setup (docker compose):

docker-compose up -d

See Docker Setup Documentation for detailed configuration.

πŸ“š Documentation

πŸ”§ Code Generation

Accelerate development with the Visual Studio extension:

2022.mp4

πŸ—„οΈ Database Support

Database Provider Name Status
SQL Server mssql βœ… Fully Supported
PostgreSQL postgresql βœ… Fully Supported
SQLite sqlite βœ… Fully Supported

Configure in appsettings.json:

{
  "DatabaseSettings": {
    "DBProvider": "mssql",
    "ConnectionString": "Server=localhost;Database=YourDb;Trusted_Connection=true;"
  }
}

πŸ” Authentication Providers

Configure OAuth providers in appsettings.json:

πŸš€ Docker Setup for Blazor Server Application

Pull the Docker Image

docker pull blazordevlab/cleanarchitectureblazorserver:latest

Run the Docker Container

For Development:

docker run -p 8443:443 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_HTTPS_PORTS=443 \
  -e DatabaseSettings__DBProvider=mssql \
  -e DatabaseSettings__ConnectionString="Server=127.0.0.1;Database=BlazorDashboardDb;User Id=sa;Password=<YourPassword>;MultipleActiveResultSets=true;Encrypt=false;TrustServerCertificate=false" \
  blazordevlab/cleanarchitectureblazorserver:latest

For Production (Persistent Database and SMTP Configuration):

docker run -d -p 8443:443 \
-e ASPNETCORE_ENVIRONMENT=Development \
-e ASPNETCORE_HTTP_PORTS=80 \
-e ASPNETCORE_HTTPS_PORTS=443 \
-e DatabaseSettings__DBProvider=mssql \
-e DatabaseSettings__ConnectionString="Server=127.0.0.1;Database=BlazorDashboardDb;User Id=sa;Password=<YourPassword>;MultipleActiveResultSets=true;Encrypt=false;TrustServerCertificate=false" \
-e SmtpClientOptions__User=<YourSMTPUser> \
-e SmtpClientOptions__Port=25 \
-e SmtpClientOptions__Server=<YourSMTPServer> \
-e SmtpClientOptions__Password=<YourSMTPPassword> \
-e Authentication__Microsoft__ClientId=<YourMicrosoftClientId> \
-e Authentication__Microsoft__ClientSecret=<YourMicrosoftClientSecret> \
-e Authentication__Google__ClientId=<YourGoogleClientId> \
-e Authentication__Google__ClientSecret=<YourGoogleClientSecret> \
-e Authentication__Facebook__AppId=<YourFacebookAppId> \
-e Authentication__Facebook__AppSecret=<YourFacebookAppSecret> \
blazordevlab/cleanarchitectureblazorserver:latest

Docker Compose Setup

For easier management, use a docker-compose.yml file:

version: '3.8'
services:
  blazorserverapp:
    image: blazordevlab/cleanarchitectureblazorserver:latest
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80;https://+:443
      - ASPNETCORE_HTTP_PORTS=80
      - ASPNETCORE_HTTPS_PORTS=443
      - DatabaseSettings__DBProvider=mssql
      - DatabaseSettings__ConnectionString=Server=127.0.0.1;Database=BlazorDashboardDb;User Id=sa;Password=***;MultipleActiveResultSets=true;Encrypt=false;TrustServerCertificate=false
      - SmtpClientOptions__User=<YourSMTPUser>
      - SmtpClientOptions__Port=25
      - SmtpClientOptions__Server=<YourSMTPServer>
      - SmtpClientOptions__Password=<YourSMTPPassword>
      - Authentication__Microsoft__ClientId=<YourMicrosoftClientId>
      - Authentication__Microsoft__ClientSecret=<YourMicrosoftClientSecret>
      - Authentication__Google__ClientId=<YourGoogleClientId>
      - Authentication__Google__ClientSecret=<YourGoogleClientSecret>
      - Authentication__Facebook__AppId=<YourFacebookAppId>
      - Authentication__Facebook__AppSecret=<YourFacebookAppSecret>
    ports:
      - "8443:443"
    volumes:
      - files_volume:/app/Files

  mssql:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=YourStrongPassword!
    ports:
      - "1433:1433"
    volumes:
      - mssql_data:/var/opt/mssql

volumes:
  files_volume:
  mssql_data:

SQL Server Database Migrations

Install the EF Core CLI version that matches the project:

dotnet tool install --global dotnet-ef --version 10.0.11

Create a migration and apply it to the configured SQL Server database:

dotnet ef migrations add <MigrationName> --project src/Migrators/Migrators.MSSQL/Migrators.MSSQL.csproj --startup-project src/Server.UI/Server.UI.csproj --context ApplicationDbContext --output-dir Migrations
dotnet ef database update --project src/Migrators/Migrators.MSSQL/Migrators.MSSQL.csproj --startup-project src/Server.UI/Server.UI.csproj --context ApplicationDbContext

🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

πŸ“– Learning Resources

Video Tutorials

Adding Contact Entity Tutorial: Adding a Contact Entity

Removing Customer Object Tutorial: Removing a Customer Object

Related Projects

🌐 About the Creator

Visit my website for more Blazor resources and professional services:

BlazorServer.com - Blazor Development Services & Resources

❀️ Support This Project

If this project helps you, please consider supporting its development:

  • ⭐ Star this repository
  • πŸ› Report issues
  • πŸ’‘ Suggest features
  • πŸ’° Sponsor: GitHub Sponsors | PayPal

Your support helps maintain and improve this project. Thank you! πŸ™

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Built with ❀️ using Clean Architecture principles

⭐ Star this repo | πŸ› Report Bug | πŸ’‘ Request Feature

About

This repository is designed to create TrdBx Blazor Server application

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages