An open API service indexing awesome lists of open source software.

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.

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