-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Docs/project overview onboarding #978
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1227d4d
5de27e8
ca2b524
d29870a
896a0b4
a2b0c7f
1094035
93509ed
0663d44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // For format details, see https://aka.ms/devcontainer.json. For config options, see the | ||
| // README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu | ||
| { | ||
| "name": "Ubuntu", | ||
| // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile | ||
| "image": "mcr.microsoft.com/devcontainers/base:noble", | ||
| "features": { | ||
| "ghcr.io/devcontainers/features/copilot-cli:1": {}, | ||
| "ghcr.io/devcontainers/features/dotnet:2": { | ||
| "version": "10.0", | ||
| "additionalVersions": "7.0, 8.0, 9.0" | ||
| }, | ||
| "ghcr.io/devcontainers/features/azure-cli:1": {}, | ||
| "ghcr.io/devcontainers/features/github-cli:1": {}, | ||
| "ghcr.io/devcontainers/features/docker-in-docker:2": {}, | ||
| "ghcr.io/devcontainers/features/git-lfs:1": {}, | ||
| "ghcr.io/devcontainers/features/powershell:2": {}, | ||
| "ghcr.io/dotnet/aspire-devcontainer-feature/dotnetaspire:1": {}, | ||
| "ghcr.io/daniellindemann/dev-container-features/dotnet-usersecrets-persistence:0": {}, | ||
| "ghcr.io/devcontainers/features/terraform:1": {} | ||
| }, | ||
|
|
||
| // Features to add to the dev container. More info: https://containers.dev/features. | ||
| // "features": {}, | ||
|
|
||
| // Use 'forwardPorts' to make a list of ports inside the container available locally. | ||
| // "forwardPorts": [], | ||
|
|
||
| // Use 'postCreateCommand' to run commands after the container is created. | ||
| "postCreateCommand": "dotnet run eShop.slnx --project src/eShop.AppHost/eShop.AppHost.csproj" | ||
|
|
||
| // Configure tool-specific properties. | ||
| // "customizations": {}, | ||
|
|
||
| // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. | ||
| // "remoteUser": "root" | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,189 @@ | ||||||
| # eShop – Project Overview & Onboarding Guide | ||||||
|
|
||||||
| ## Business Purpose | ||||||
|
|
||||||
| **eShop** is a reference .NET application implementing a fully functional e-commerce website ("AdventureWorks"). It demonstrates modern **microservices architecture** patterns using **.NET Aspire** and serves as a best-practice blueprint for building scalable, cloud-ready applications. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Main Features | ||||||
|
|
||||||
| | Feature | Description | | ||||||
| |---|---| | ||||||
| | Product Catalog | Browse, search, and filter products with AI-powered recommendations | | ||||||
| | Shopping Basket | Cart management backed by Redis | | ||||||
| | Order Processing | Full order lifecycle with grace period and state machine | | ||||||
| | Payment Processing | Event-driven payment handling | | ||||||
| | Authentication | OpenID Connect / JWT via Duende IdentityServer | | ||||||
| | Webhooks | External system integration via webhook subscriptions | | ||||||
| | Web UI | Blazor Interactive Server web application | | ||||||
| | Mobile App | Cross-platform .NET MAUI application | | ||||||
| | AI Integration | Product recommendations via OpenAI / Azure OpenAI / Ollama | | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Architecture Overview | ||||||
|
|
||||||
| This is a **true microservices architecture** orchestrated by **.NET Aspire**. | ||||||
|
|
||||||
| ``` | ||||||
| ┌─────────────────────────────────────────────────────────────┐ | ||||||
| │ eShop.AppHost │ | ||||||
| │ (.NET Aspire Orchestration Host) │ | ||||||
| └──────────────────────────┬──────────────────────────────────┘ | ||||||
| │ Manages | ||||||
| ┌──────────────────┼──────────────────┐ | ||||||
| ▼ ▼ ▼ | ||||||
| ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ | ||||||
| │ Identity.API │ │ Catalog.API │ │ Basket.API │ | ||||||
| │ (AuthN/Z) │ │ (Products) │ │ (Cart + Redis) │ | ||||||
| └──────────────┘ └──────────────┘ └──────────────────┘ | ||||||
| ┌──────────────────┬──────────────────┐ | ||||||
| ▼ ▼ ▼ | ||||||
| ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ | ||||||
| │ Ordering.API │ │ Webhooks.API │ │ OrderProcessor │ | ||||||
| │ (Orders) │ │ (Webhooks) │ │ PaymentProcessor │ | ||||||
| └──────────────┘ └──────────────┘ └──────────────────┘ | ||||||
| ┌──────────────────┬──────────────────┐ | ||||||
| ▼ ▼ ▼ | ||||||
| ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ | ||||||
| │ WebApp │ │ HybridApp │ │ WebhookClient │ | ||||||
| │ (Blazor) │ │ (MAUI) │ │ (Test Client) │ | ||||||
| └──────────────┘ └──────────────┘ └──────────────────┘ | ||||||
|
|
||||||
| Infrastructure: PostgreSQL + pgvector | Redis | RabbitMQ | ||||||
| ``` | ||||||
|
|
||||||
| ### Key Architecture Patterns | ||||||
|
|
||||||
| - **CQRS** – Commands/Queries separated via MediatR (see `Ordering.API/Application/`) | ||||||
| - **Domain-Driven Design (DDD)** – Aggregates, Value Objects, Domain Events in `Ordering.Domain` | ||||||
| - **Event-Driven** – Integration events published over RabbitMQ between services | ||||||
| - **Transactional Outbox** – `IntegrationEventLogEF` ensures reliable event delivery | ||||||
| - **Repository Pattern** – Abstracted data access in `Ordering.Infrastructure` | ||||||
| - **gRPC** – High-performance communication for Basket service | ||||||
| - **Idempotency** – Duplicate request detection via `IdentifiedCommand<T>` | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Key Technologies & Frameworks | ||||||
|
|
||||||
| | Category | Technology | Version | | ||||||
| |---|---|---| | ||||||
| | Runtime | .NET SDK | 10.0 | | ||||||
| | Orchestration | .NET Aspire | 13.1.0 | | ||||||
| | Web Framework | ASP.NET Core / Blazor | 10.0 | | ||||||
| | Mobile | .NET MAUI | Latest | | ||||||
| | CQRS / Mediator | MediatR | 13.0.0 | | ||||||
| | ORM | Entity Framework Core | 10.0.1 | | ||||||
| | Database | PostgreSQL + pgvector | – | | ||||||
| | Cache | Redis | – | | ||||||
| | Message Bus | RabbitMQ | – | | ||||||
| | Identity | Duende IdentityServer | 7.3.2 | | ||||||
| | gRPC | gRPC.AspNetCore | 2.71.0 | | ||||||
| | Validation | FluentValidation | 12.0.0 | | ||||||
| | Observability | OpenTelemetry | 1.14.0 | | ||||||
| | API Versioning | Asp.Versioning | 8.1.0 | | ||||||
| | API Docs | Scalar / OpenAPI | 2.8.6 | | ||||||
| | AI | Azure OpenAI / Ollama | Beta | | ||||||
| | Testing | MSTest + Playwright | – | | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Repository Structure | ||||||
|
|
||||||
| ``` | ||||||
| eShop/ | ||||||
| ├── src/ | ||||||
| │ ├── eShop.AppHost/ # ▶ PRIMARY ENTRY POINT – Aspire orchestration | ||||||
| │ ├── eShop.ServiceDefaults/ # Shared service config (health, auth, OpenAPI) | ||||||
| │ ├── Identity.API/ # Authentication & authorization | ||||||
| │ ├── Catalog.API/ # Product catalog + AI recommendations | ||||||
| │ ├── Basket.API/ # Shopping cart (Redis + gRPC) | ||||||
| │ ├── Ordering.API/ # Order management (CQRS, REST) | ||||||
| │ ├── Ordering.Domain/ # DDD aggregates & domain events | ||||||
| │ ├── Ordering.Infrastructure/ # EF Core persistence & repositories | ||||||
| │ ├── Webhooks.API/ # External webhook management | ||||||
| │ ├── OrderProcessor/ # Background: order grace period state machine | ||||||
| │ ├── PaymentProcessor/ # Background: payment event handling | ||||||
| │ ├── WebApp/ # Blazor Interactive Server frontend | ||||||
| │ ├── WebAppComponents/ # Shared Razor component library | ||||||
| │ ├── HybridApp/ # .NET MAUI mobile app | ||||||
| │ ├── ClientApp/ # Mobile client app | ||||||
| │ ├── WebhookClient/ # Webhook test client | ||||||
| │ ├── EventBus/ # Event bus abstraction | ||||||
| │ ├── EventBusRabbitMQ/ # RabbitMQ event bus implementation | ||||||
| │ └── IntegrationEventLogEF/ # Outbox pattern implementation | ||||||
| ├── tests/ | ||||||
| │ ├── Basket.UnitTests/ | ||||||
| │ ├── Ordering.UnitTests/ | ||||||
| │ ├── Ordering.FunctionalTests/ | ||||||
| │ ├── Catalog.FunctionalTests/ | ||||||
| │ └── ClientApp.UnitTests/ | ||||||
| ├── e2e/ # Playwright end-to-end tests | ||||||
| ├── docs/ # Documentation | ||||||
| ├── .github/workflows/ # CI/CD pipelines | ||||||
| ├── eShop.slnx # Full solution | ||||||
| ├── eShop.Web.slnf # Web projects solution filter | ||||||
| ├── Directory.Packages.props # Centralized NuGet package versions | ||||||
| └── global.json # SDK version pin | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Important Entry Points & Components | ||||||
|
|
||||||
| ### Starting the Application | ||||||
|
|
||||||
| ```powershell | ||||||
| dotnet run --project src/eShop.AppHost/eShop.AppHost.csproj | ||||||
| ``` | ||||||
|
|
||||||
| The **Aspire Dashboard** URL is printed to the console — use it to monitor all services, traces, logs, and metrics. | ||||||
|
|
||||||
| ### Key Files | ||||||
|
|
||||||
| | File | Purpose | | ||||||
| |---|---| | ||||||
| | `src/eShop.AppHost/Program.cs` | Service composition – wires all microservices, databases, and message brokers | | ||||||
| | `src/WebApp/Program.cs` | Blazor web app startup | | ||||||
| | `src/Ordering.API/Application/` | CQRS commands, queries, handlers, and MediatR pipeline behaviors | | ||||||
| | `src/Ordering.Domain/AggregatesModel/` | DDD aggregates: `OrderAggregate`, `BuyerAggregate` | | ||||||
| | `src/EventBusRabbitMQ/RabbitMQEventBus.cs` | Event bus implementation | | ||||||
| | `src/eShop.ServiceDefaults/Extensions.cs` | Common extensions applied to all services | | ||||||
| | `Directory.Packages.props` | Central place to update NuGet dependency versions | | ||||||
|
|
||||||
| ### Key API Endpoints | ||||||
|
|
||||||
| | Service | Endpoint | Description | | ||||||
| |---|---|---| | ||||||
| | Ordering.API | `POST /api/orders/` | Create a new order | | ||||||
| | Ordering.API | `GET /api/orders/{id}` | Get order by ID | | ||||||
| | Ordering.API | `PUT /api/orders/cancel` | Cancel an order | | ||||||
| | Ordering.API | `PUT /api/orders/ship` | Ship an order | | ||||||
| | Catalog.API | `GET /api/catalog/items` | List catalog items | | ||||||
| | Basket.API | gRPC `BasketService` | Manage shopping basket | | ||||||
| | Identity.API | `/.well-known/openid-configuration` | OIDC discovery endpoint | | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## CI/CD | ||||||
|
|
||||||
| | Workflow | Trigger | What it does | | ||||||
| |---|---|---| | ||||||
| | `pr-validation.yml` | PR / push to `main` | Build + test all web projects | | ||||||
| | `pr-validation-maui.yml` | PR / push to `main` | Build + test MAUI app | | ||||||
| | `playwright.yml` | Scheduled / manual | End-to-end browser tests | | ||||||
| | `markdownlint.yml` | PR | Lint documentation | | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Deployment | ||||||
|
|
||||||
| ```bash | ||||||
| # Azure (via Azure Developer CLI) | ||||||
| azd init | ||||||
| azd up | ||||||
| ``` | ||||||
|
|
||||||
| Aspire auto-detects all services and provisions Azure Container Apps, PostgreSQL, Redis, and Service Bus. | ||||||
|
||||||
| Aspire auto-detects all services and provisions Azure Container Apps, PostgreSQL, Redis, and Service Bus. | |
| Aspire auto-detects all services and provisions Azure Container Apps, PostgreSQL, Redis, and a message broker (RabbitMQ in this sample). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
postCreateCommandrunsdotnet run ..., which is a long-running process and will block devcontainer creation/initialization. Also,dotnet run eShop.slnx --project ...will passeShop.slnxas an app argument rather than selecting a project to run. UsepostCreateCommandfor one-time setup (e.g., restore/build) and leavedotnet run --project src/eShop.AppHost/eShop.AppHost.csprojas a manual step (or move it to a more appropriate hook if you truly want auto-start).