A production-ready Blazor Server application with MudBlazor, EF Core (SQL Server), Repository + Specification patterns, and FluentValidation.
BlazorOrderApp/
├── Domain/
│ ├── Entities/
│ │ ├── Order.cs # Master entity + OrderStatus enum
│ │ └── OrderItem.cs # Detail entity
│ └── Specifications/
│ ├── BaseSpecification.cs # Generic specification base
│ └── OrderSpecifications.cs # Filtered, paged, by-id specs
│
├── Application/
│ ├── DTOs/
│ │ └── OrderDtos.cs # OrderDto, OrderItemDto, CreateOrderDto, PagedResult<T>
│ ├── Interfaces/
│ │ ├── IRepository.cs # Generic repository contract
│ │ ├── IOrderRepository.cs # Order-specific contract
│ │ └── IOrderService.cs # Service contract
│ ├── Services/
│ │ └── OrderService.cs # All CRUD + business logic
│ └── Validators/
│ └── OrderValidators.cs # FluentValidation rules
│
├── Infrastructure/
│ ├── Data/
│ │ ├── AppDbContext.cs # EF Core DbContext with seed data
│ │ └── SpecificationEvaluator.cs # Translates spec → IQueryable
│ └── Repositories/
│ ├── Repository.cs # Generic EF Core implementation
│ └── OrderRepository.cs # Order-specific (GenerateOrderNumber)
│
└── Web/
├── App.razor # Root HTML shell
├── Routes.razor
├── _Imports.razor
├── Components/
│ ├── Layout/
│ │ └── MainLayout.razor # AppBar + Drawer + MudTheme
│ ├── Pages/
│ │ ├── Index.razor # Dashboard with KPI cards
│ │ ├── Orders.razor # Master list + filter + pagination
│ │ └── OrderDetail.razor # Detail view + inline item CRUD
│ ├── Dialogs/
│ │ ├── OrderDialog.razor # Create / Edit order dialog
│ │ ├── OrderItemDialog.razor # Add / Edit single item
│ │ └── ConfirmDialog.razor # Reusable delete confirmation
│ └── Shared/
│ └── OrderStatusChip.razor # Colored status badge
└── Program.cs # DI, EF, MudBlazor registration
Edit appsettings.json:
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=BlazorOrderApp;Trusted_Connection=True;"
}# Add first migration
dotnet ef migrations add InitialCreate --output-dir Infrastructure/Data/Migrations
# Apply to database (also runs automatically on startup via MigrateAsync)
dotnet ef database updatedotnet runNavigate to https://localhost:5001
| Feature | Implementation |
|---|---|
| Master list | Orders.razor — MudTable with server-side data |
| Detail view | OrderDetail.razor — customer card + items table |
| Create order | OrderDialog.razor — dynamic item rows, live total |
| Edit order | Same dialog, pre-populated |
| Delete order | ConfirmDialog.razor — guard against accidents |
| Add / edit / delete items | OrderItemDialog.razor + inline icon actions |
| Update status | Inline MudSelect on detail page |
| Filtering | Search term, status, date range |
| Pagination | OrdersFilteredSpecification with Skip/Take |
| Validation | FluentValidation — errors shown inline |
| Repository pattern | IRepository<T> + IOrderRepository |
| Specification pattern | BaseSpecification<T> + SpecificationEvaluator |
| Seed data | 3 orders × multiple items in OnModelCreating |
| Dashboard | KPI cards (total, pending, delivered, revenue) |
// Define the query as a reusable object
var spec = new OrdersFilteredSpecification(filter);
var orders = await _orderRepo.GetAsync(spec);// Injected via IOrderRepository
await _orderRepo.AddAsync(order);
await _orderRepo.UpdateAsync(order);
await _orderRepo.DeleteAsync(order);var validator = new CreateOrderValidator();
var result = await validator.ValidateAsync(model);
if (!result.IsValid) { /* show errors */ }