https://github.com/fajarnugraha37/dotnet-xunit
This guide explains how to set up a multi-module (multi-project) solution in .NET, where each module is a separate project (for example, Core, Data, API) that can reference each other as needed.
https://github.com/fajarnugraha37/dotnet-xunit
csharp docker docker-compose dotnet dotnet-core entity-framework entity-framework-core moq postgresql unit-test unit-testing xunit
Last synced: 15 days ago
JSON representation
This guide explains how to set up a multi-module (multi-project) solution in .NET, where each module is a separate project (for example, Core, Data, API) that can reference each other as needed.
- Host: GitHub
- URL: https://github.com/fajarnugraha37/dotnet-xunit
- Owner: fajarnugraha37
- License: mit
- Created: 2025-07-26T19:17:56.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-07-26T19:19:40.000Z (11 months ago)
- Last Synced: 2026-04-16T17:43:53.811Z (about 2 months ago)
- Topics: csharp, docker, docker-compose, dotnet, dotnet-core, entity-framework, entity-framework-core, moq, postgresql, unit-test, unit-testing, xunit
- Language: C#
- Homepage:
- Size: 25.4 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Multi-Module Project Setup in .NET
This guide explains how to set up a **multi-module (multi-project) solution** in .NET, where each module is a separate project (for example, Core, Data, API) that can reference each other as needed.
---
## 1. Create a Solution
Open your terminal and run:
```sh
dotnet new sln -n VibeCoding
cd VibeCoding
```
---
## 2. Create Projects (Modules)
Create the required projects. Example:
```sh
dotnet new classlib -n VibeCoding.Core # Core business logic
dotnet new classlib -n VibeCoding.Data # Data access
dotnet new webapi -n VibeCoding.Api # Web API project (uses net9.0)
dotnet new xunit -n VibeCoding.Tests # Test project (uses net9.0)
```
---
## 3. Add PostgreSQL & Entity Framework Core
1. **Add NuGet packages:**
```sh
dotnet add VibeCoding.Data package Npgsql.EntityFrameworkCore.PostgreSQL --prerelease
dotnet add VibeCoding.Data package Microsoft.EntityFrameworkCore.Design --prerelease
dotnet add VibeCoding.Api package Npgsql.EntityFrameworkCore.PostgreSQL --prerelease
dotnet add VibeCoding.Api package Microsoft.EntityFrameworkCore.Design --prerelease
```
2. **Create your DbContext** in `VibeCoding.Data/Model/AppDbContext.cs`:
```csharp
using Microsoft.EntityFrameworkCore;
namespace VibeCoding.Data.Model
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options)
: base(options)
{
}
// Add DbSet properties here
}
}
```
3. **Add connection string** to `VibeCoding.Api/appsettings.json`:
```json
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=vibecoding;Username=postgres;Password=yourpassword"
}
}
```
4. **Register DbContext in DI** in `VibeCoding.Api/Program.cs`:
```csharp
builder.Services.AddDbContext(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
```
5. **Run EF Core migrations:**
```sh
dotnet tool install --global dotnet-ef
dotnet ef migrations add InitialCreate --project VibeCoding.Data --startup-project VibeCoding.Api
dotnet ef database update --project VibeCoding.Data --startup-project VibeCoding.Api
```
6. **Add Changes to User Model** in `VibeCoding.Data/Model/User.cs`:
```csharp
namespace VibeCoding.Data.Model;
public class User : BaseEntity
{
public int Id { get; set; }
public string Username { get; set; } = default!;
public string Email { get; set; } = default!;
public string PasswordHash { get; set; } = default!;
// Email verification
public bool EmailVerified { get; set; } = false;
public string? EmailVerificationToken { get; set; }
public DateTime? EmailVerificationTokenExpiresAt { get; set; }
// Password reset
public string? PasswordResetToken { get; set; }
public DateTime? PasswordResetTokenExpiresAt { get; set; }
}
```
```sh
dotnet ef migrations add AddUserAndBaseEntity --project VibeCoding.Data --startup-project VibeCoding.Api
dotnet ef database update --project VibeCoding.Data --startup-project VibeCoding.Api
```
---
## 4. Add Projects to the Solution
```sh
dotnet sln add VibeCoding.Core/VibeCoding.Core.csproj
dotnet sln add VibeCoding.Data/VibeCoding.Data.csproj
dotnet sln add VibeCoding.Api/VibeCoding.Api.csproj
dotnet sln add VibeCoding.Tests/VibeCoding.Tests.csproj
```
---
## 5. Set Up Project References
```sh
dotnet sln add VibeCoding.Core/VibeCoding.Core.csproj
dotnet sln add VibeCoding.Data/VibeCoding.Data.csproj
dotnet sln add VibeCoding.Api/VibeCoding.Api.csproj
dotnet sln add VibeCoding.Tests/VibeCoding.Tests.csproj
```
---
## 5. Set Up Project References
Reference the modules as needed. For example, if `VibeCoding.Api` needs to use both core and data logic:
```sh
dotnet add VibeCoding.Api/VibeCoding.Api.csproj reference VibeCoding.Core/VibeCoding.Core.csproj
dotnet add VibeCoding.Api/VibeCoding.Api.csproj reference VibeCoding.Data/VibeCoding.Data.csproj
```
If `VibeCoding.Data` needs to use `VibeCoding.Core`:
```sh
dotnet add VibeCoding.Core/VibeCoding.Core.csproj reference VibeCoding.Data/VibeCoding.Data.csproj
dotnet add VibeCoding.Data/VibeCoding.Data.csproj reference VibeCoding.Core/VibeCoding.Core.csproj
```
If your test project needs to test all modules:
```sh
dotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Api/VibeCoding.Api.csproj
dotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Data/VibeCoding.Data.csproj
dotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Core/VibeCoding.Core.csproj
```
---
## 6. Build the Solution
```sh
dotnet build
```
---
## 7. Directory Structure Example
```
VibeCoding/
VibeCoding.Core/
VibeCoding.Core.csproj
VibeCoding.Data/
VibeCoding.Data.csproj
VibeCoding.Api/
VibeCoding.Api.csproj
VibeCoding.Tests/
VibeCoding.Tests.csproj
VibeCoding.sln
```
---
## 8. Develop, Test, and Run
- Add your code to each module as needed.
- To run the Web API:
```sh
dotnet run --project VibeCoding.Api
```
- To run all tests:
```sh
dotnet test
```
---
## 9. Docker Support
- Build the Docker image:
```sh
docker build -t vibecoding-api .
```
- Run the container:
```sh
docker run -p 8080:80 vibecoding-api
```
---
## 10. Tips and Best Practices
- Organize new modules as separate projects (e.g., `VibeCoding.Services`, `VibeCoding.Tests`).
- Use project references (`dotnet add ... reference ...`) for inter-project dependencies during development.
- Keep modules loosely coupled with well-defined interfaces.
- Use solution folders in Visual Studio for better organization if needed.
- Use the latest .NET version (e.g., `net9.0`) for all projects for consistency.
---
## 11. Additional Resources
- [.NET CLI documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/)
- [Entity Framework Core Docs](https://learn.microsoft.com/en-us/ef/core/)
---
## 12. Running Unit Tests with Coverage
You can run all unit tests and generate a coverage report using the Makefile:
```sh
make test
```
This will:
- Run all tests in `VibeCoding.Tests` with coverage collection enabled.
- Generate an HTML coverage report in the `coverage-report` directory.
To view the coverage report, open `coverage-report/index.html` in your browser.
---
## 13. Docker & Docker Compose
- **Build the Docker image:**
```sh
make docker-build
```
- **Run the API container:**
```sh
make docker-run
```
- **Stop and remove the API container/image:**
```sh
make docker-clean
```
- **Start the full stack (API + PostgreSQL) with Docker Compose:**
```sh
make compose-up
```
- **Stop all containers:**
```sh
make compose-down
```
- **View logs:**
```sh
make compose-logs
```
- **Restart and recreate only the API container:**
```sh
make compose-restart-api
```
---
## 14. Requirements
- [.NET 9 SDK](https://dotnet.microsoft.com/)
- [Docker](https://www.docker.com/)
- [ReportGenerator](https://github.com/danielpalme/ReportGenerator) (for HTML coverage reports, installed automatically if you use the Makefile)
---
## 15. References
- [Entity Framework Core Docs](https://learn.microsoft.com/en-us/ef/core/)
- [Npgsql Docs](https://www.npgsql.org/efcore/)
- [Coverlet Coverage](https://github.com/coverlet-coverage/coverlet)
- [ReportGenerator](https://github.com/danielpalme/ReportGenerator)
- [.NET CLI documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/)
---
## 16. Authentication & JWT Setup
### JWT Secret Configuration
You must set a JWT secret in your `VibeCoding.Api/appsettings.json`:
```json
"Jwt": {
"Secret": "your_super_secret_key_at_least_32_chars_long"
}
```
Replace with a strong, random string (minimum 32 characters).
---
### Auth API Endpoints
| Endpoint | Method | Body Example | Description |
|----------------------------------|--------|------------------------------------------------------------------------------|-----------------------------------|
| `/api/auth/register` | POST | `{ "username": "user", "email": "mail", "password": "pass" }` | Register new user |
| `/api/auth/login` | POST | `{ "usernameOrEmail": "user", "password": "pass" }` | Login, returns JWT & refresh |
| `/api/auth/refresh` | POST | `{ "refreshToken": "..." }` | Refresh JWT using refresh token |
| `/api/auth/verify-email` | POST | `{ "token": "..." }` | Verify email with token |
| `/api/auth/request-password-reset`| POST | `{ "email": "mail" }` | Request password reset |
| `/api/auth/reset-password` | POST | `{ "token": "...", "newPassword": "..." }` | Reset password with token |
All endpoints validate input and return appropriate error codes/messages.
---
### Postman Collection
A ready-to-use Postman collection is available at [`postman-collection.json`](postman-collection.json).
---
### Running the API
- Make sure your database and JWT secret are configured.
- Run the API:
```sh
dotnet run --project VibeCoding.Api
```
- The API will be available at `http://localhost:8080` (or as configured).
---
### Running Tests
- Run all tests and generate coverage:
```sh
make test
```
- Coverage report will be in `coverage-report/index.html`.
---
### Dependencies for Auth & Testing
- `System.IdentityModel.Tokens.Jwt`
- `Microsoft.IdentityModel.Tokens`
- `Moq` (for controller unit tests)
- `Microsoft.AspNetCore.Mvc`
- `Microsoft.Extensions.Configuration.Abstractions`
Install with:
```sh
dotnet add VibeCoding.Api package System.IdentityModel.Tokens.Jwt
dotnet add VibeCoding.Api package Microsoft.IdentityModel.Tokens
dotnet add VibeCoding.Tests package Moq
dotnet add VibeCoding.Tests package Microsoft.AspNetCore.Mvc
dotnet add VibeCoding.Tests package Microsoft.Extensions.Configuration.Abstractions
```
---
## 17. Security Notes
- Always use HTTPS in production.
- Store secrets (like JWT secret) securely (environment variables or secret managers).
- Use strong passwords and consider using a stronger password hashing algorithm (e.g., BCrypt) for