{"id":50311246,"url":"https://github.com/fajarnugraha37/dotnet-xunit","last_synced_at":"2026-05-28T21:01:36.178Z","repository":{"id":351826727,"uuid":"1026862780","full_name":"fajarnugraha37/dotnet-xunit","owner":"fajarnugraha37","description":"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.","archived":false,"fork":false,"pushed_at":"2025-07-26T19:19:40.000Z","size":26,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T17:43:53.811Z","etag":null,"topics":["csharp","docker","docker-compose","dotnet","dotnet-core","entity-framework","entity-framework-core","moq","postgresql","unit-test","unit-testing","xunit"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fajarnugraha37.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-26T19:17:56.000Z","updated_at":"2025-07-27T12:59:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fajarnugraha37/dotnet-xunit","commit_stats":null,"previous_names":["fajarnugraha37/dotnet-xunit"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/fajarnugraha37/dotnet-xunit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fdotnet-xunit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fdotnet-xunit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fdotnet-xunit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fdotnet-xunit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fajarnugraha37","download_url":"https://codeload.github.com/fajarnugraha37/dotnet-xunit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fdotnet-xunit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33626142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","docker","docker-compose","dotnet","dotnet-core","entity-framework","entity-framework-core","moq","postgresql","unit-test","unit-testing","xunit"],"created_at":"2026-05-28T21:01:35.100Z","updated_at":"2026-05-28T21:01:36.172Z","avatar_url":"https://github.com/fajarnugraha37.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multi-Module Project Setup in .NET\n\nThis 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.\n\n---\n\n## 1. Create a Solution\n\nOpen your terminal and run:\n\n```sh\ndotnet new sln -n VibeCoding\ncd VibeCoding\n```\n\n---\n\n## 2. Create Projects (Modules)\n\nCreate the required projects. Example:\n\n```sh\ndotnet new classlib -n VibeCoding.Core       # Core business logic\ndotnet new classlib -n VibeCoding.Data       # Data access\ndotnet new webapi   -n VibeCoding.Api        # Web API project (uses net9.0)\ndotnet new xunit    -n VibeCoding.Tests      # Test project (uses net9.0)\n```\n\n---\n\n## 3. Add PostgreSQL \u0026 Entity Framework Core\n\n1. **Add NuGet packages:**\n   ```sh\n   dotnet add VibeCoding.Data package Npgsql.EntityFrameworkCore.PostgreSQL --prerelease\n   dotnet add VibeCoding.Data package Microsoft.EntityFrameworkCore.Design --prerelease\n   dotnet add VibeCoding.Api package Npgsql.EntityFrameworkCore.PostgreSQL --prerelease\n   dotnet add VibeCoding.Api package Microsoft.EntityFrameworkCore.Design --prerelease\n   ```\n\n2. **Create your DbContext** in `VibeCoding.Data/Model/AppDbContext.cs`:\n   ```csharp\n   using Microsoft.EntityFrameworkCore;\n\n   namespace VibeCoding.Data.Model\n   {\n       public class AppDbContext : DbContext\n       {\n           public AppDbContext(DbContextOptions\u003cAppDbContext\u003e options)\n               : base(options)\n           {\n           }\n           // Add DbSet\u003cT\u003e properties here\n       }\n   }\n   ```\n\n3. **Add connection string** to `VibeCoding.Api/appsettings.json`:\n   ```json\n   {\n     \"ConnectionStrings\": {\n       \"DefaultConnection\": \"Host=localhost;Database=vibecoding;Username=postgres;Password=yourpassword\"\n     }\n   }\n   ```\n\n4. **Register DbContext in DI** in `VibeCoding.Api/Program.cs`:\n   ```csharp\n   builder.Services.AddDbContext\u003cAppDbContext\u003e(options =\u003e\n       options.UseNpgsql(builder.Configuration.GetConnectionString(\"DefaultConnection\")));\n   ```\n\n5. **Run EF Core migrations:**\n   ```sh\n   dotnet tool install --global dotnet-ef\n   dotnet ef migrations add InitialCreate --project VibeCoding.Data --startup-project VibeCoding.Api\n   dotnet ef database update --project VibeCoding.Data --startup-project VibeCoding.Api\n   ```\n6. **Add Changes to User Model** in `VibeCoding.Data/Model/User.cs`:\n   ```csharp\n   namespace VibeCoding.Data.Model;\n\n   public class User : BaseEntity\n   {\n       public int Id { get; set; }\n       public string Username { get; set; } = default!;\n       public string Email { get; set; } = default!;\n       public string PasswordHash { get; set; } = default!;\n\n       // Email verification\n       public bool EmailVerified { get; set; } = false;\n       public string? EmailVerificationToken { get; set; }\n       public DateTime? EmailVerificationTokenExpiresAt { get; set; }\n\n       // Password reset\n       public string? PasswordResetToken { get; set; }\n       public DateTime? PasswordResetTokenExpiresAt { get; set; }\n   }\n   ```\n\n   ```sh\n   dotnet ef migrations add AddUserAndBaseEntity --project VibeCoding.Data --startup-project VibeCoding.Api\n   dotnet ef database update --project VibeCoding.Data --startup-project VibeCoding.Api\n   ```\n\n---\n\n## 4. Add Projects to the Solution\n\n```sh\ndotnet sln add VibeCoding.Core/VibeCoding.Core.csproj\ndotnet sln add VibeCoding.Data/VibeCoding.Data.csproj\ndotnet sln add VibeCoding.Api/VibeCoding.Api.csproj\ndotnet sln add VibeCoding.Tests/VibeCoding.Tests.csproj\n```\n\n---\n\n## 5. Set Up Project References\n```sh\ndotnet sln add VibeCoding.Core/VibeCoding.Core.csproj\ndotnet sln add VibeCoding.Data/VibeCoding.Data.csproj\ndotnet sln add VibeCoding.Api/VibeCoding.Api.csproj\ndotnet sln add VibeCoding.Tests/VibeCoding.Tests.csproj\n```\n\n---\n\n## 5. Set Up Project References\n\nReference the modules as needed. For example, if `VibeCoding.Api` needs to use both core and data logic:\n\n```sh\ndotnet add VibeCoding.Api/VibeCoding.Api.csproj reference VibeCoding.Core/VibeCoding.Core.csproj\ndotnet add VibeCoding.Api/VibeCoding.Api.csproj reference VibeCoding.Data/VibeCoding.Data.csproj\n```\n\nIf `VibeCoding.Data` needs to use `VibeCoding.Core`:\n\n```sh\ndotnet add VibeCoding.Core/VibeCoding.Core.csproj reference VibeCoding.Data/VibeCoding.Data.csproj\ndotnet add VibeCoding.Data/VibeCoding.Data.csproj reference VibeCoding.Core/VibeCoding.Core.csproj\n```\n\nIf your test project needs to test all modules:\n\n```sh\ndotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Api/VibeCoding.Api.csproj\ndotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Data/VibeCoding.Data.csproj\ndotnet add VibeCoding.Tests/VibeCoding.Tests.csproj reference VibeCoding.Core/VibeCoding.Core.csproj\n```\n\n---\n\n## 6. Build the Solution\n\n```sh\ndotnet build\n```\n\n---\n\n## 7. Directory Structure Example\n\n```\nVibeCoding/\n  VibeCoding.Core/\n    VibeCoding.Core.csproj\n  VibeCoding.Data/\n    VibeCoding.Data.csproj\n  VibeCoding.Api/\n    VibeCoding.Api.csproj\n  VibeCoding.Tests/\n    VibeCoding.Tests.csproj\n  VibeCoding.sln\n```\n\n---\n\n## 8. Develop, Test, and Run\n\n- Add your code to each module as needed.\n- To run the Web API:\n\n  ```sh\n  dotnet run --project VibeCoding.Api\n  ```\n\n- To run all tests:\n\n  ```sh\n  dotnet test\n  ```\n\n---\n\n## 9. Docker Support\n\n- Build the Docker image:\n  ```sh\n  docker build -t vibecoding-api .\n  ```\n- Run the container:\n  ```sh\n  docker run -p 8080:80 vibecoding-api\n  ```\n\n---\n\n## 10. Tips and Best Practices\n\n- Organize new modules as separate projects (e.g., `VibeCoding.Services`, `VibeCoding.Tests`).\n- Use project references (`dotnet add ... reference ...`) for inter-project dependencies during development.\n- Keep modules loosely coupled with well-defined interfaces.\n- Use solution folders in Visual Studio for better organization if needed.\n- Use the latest .NET version (e.g., `net9.0`) for all projects for consistency.\n\n---\n\n## 11. Additional Resources\n\n- [.NET CLI documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/)\n- [Entity Framework Core Docs](https://learn.microsoft.com/en-us/ef/core/)\n\n---\n\n## 12. Running Unit Tests with Coverage\n\nYou can run all unit tests and generate a coverage report using the Makefile:\n\n```sh\nmake test\n```\n\nThis will:\n- Run all tests in `VibeCoding.Tests` with coverage collection enabled.\n- Generate an HTML coverage report in the `coverage-report` directory.\n\nTo view the coverage report, open `coverage-report/index.html` in your browser.\n\n---\n\n## 13. Docker \u0026 Docker Compose\n\n- **Build the Docker image:**\n  ```sh\n  make docker-build\n  ```\n- **Run the API container:**\n  ```sh\n  make docker-run\n  ```\n- **Stop and remove the API container/image:**\n  ```sh\n  make docker-clean\n  ```\n- **Start the full stack (API + PostgreSQL) with Docker Compose:**\n  ```sh\n  make compose-up\n  ```\n- **Stop all containers:**\n  ```sh\n  make compose-down\n  ```\n- **View logs:**\n  ```sh\n  make compose-logs\n  ```\n- **Restart and recreate only the API container:**\n  ```sh\n  make compose-restart-api\n  ```\n\n---\n\n## 14. Requirements\n\n- [.NET 9 SDK](https://dotnet.microsoft.com/)\n- [Docker](https://www.docker.com/)\n- [ReportGenerator](https://github.com/danielpalme/ReportGenerator) (for HTML coverage reports, installed automatically if you use the Makefile)\n\n---\n\n## 15. References\n\n- [Entity Framework Core Docs](https://learn.microsoft.com/en-us/ef/core/)\n- [Npgsql Docs](https://www.npgsql.org/efcore/)\n- [Coverlet Coverage](https://github.com/coverlet-coverage/coverlet)\n- [ReportGenerator](https://github.com/danielpalme/ReportGenerator)\n- [.NET CLI documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/)\n\n---\n\n## 16. Authentication \u0026 JWT Setup\n\n### JWT Secret Configuration\n\nYou must set a JWT secret in your `VibeCoding.Api/appsettings.json`:\n\n```json\n\"Jwt\": {\n  \"Secret\": \"your_super_secret_key_at_least_32_chars_long\"\n}\n```\n\nReplace with a strong, random string (minimum 32 characters).\n\n---\n\n### Auth API Endpoints\n\n| Endpoint                        | Method | Body Example                                                                 | Description                       |\n|----------------------------------|--------|------------------------------------------------------------------------------|-----------------------------------|\n| `/api/auth/register`             | POST   | `{ \"username\": \"user\", \"email\": \"mail\", \"password\": \"pass\" }`                | Register new user                 |\n| `/api/auth/login`                | POST   | `{ \"usernameOrEmail\": \"user\", \"password\": \"pass\" }`                          | Login, returns JWT \u0026 refresh      |\n| `/api/auth/refresh`              | POST   | `{ \"refreshToken\": \"...\" }`                                                  | Refresh JWT using refresh token   |\n| `/api/auth/verify-email`         | POST   | `{ \"token\": \"...\" }`                                                         | Verify email with token           |\n| `/api/auth/request-password-reset`| POST  | `{ \"email\": \"mail\" }`                                                        | Request password reset            |\n| `/api/auth/reset-password`       | POST   | `{ \"token\": \"...\", \"newPassword\": \"...\" }`                                   | Reset password with token         |\n\nAll endpoints validate input and return appropriate error codes/messages.\n\n---\n\n### Postman Collection\n\nA ready-to-use Postman collection is available at [`postman-collection.json`](postman-collection.json).\n\n---\n\n### Running the API\n\n- Make sure your database and JWT secret are configured.\n- Run the API:\n  ```sh\n  dotnet run --project VibeCoding.Api\n  ```\n- The API will be available at `http://localhost:8080` (or as configured).\n\n---\n\n### Running Tests\n\n- Run all tests and generate coverage:\n  ```sh\n  make test\n  ```\n- Coverage report will be in `coverage-report/index.html`.\n\n---\n\n### Dependencies for Auth \u0026 Testing\n\n- `System.IdentityModel.Tokens.Jwt`\n- `Microsoft.IdentityModel.Tokens`\n- `Moq` (for controller unit tests)\n- `Microsoft.AspNetCore.Mvc`\n- `Microsoft.Extensions.Configuration.Abstractions`\n\nInstall with:\n```sh\ndotnet add VibeCoding.Api package System.IdentityModel.Tokens.Jwt\ndotnet add VibeCoding.Api package Microsoft.IdentityModel.Tokens\ndotnet add VibeCoding.Tests package Moq\ndotnet add VibeCoding.Tests package Microsoft.AspNetCore.Mvc\ndotnet add VibeCoding.Tests package Microsoft.Extensions.Configuration.Abstractions\n```\n\n---\n\n## 17. Security Notes\n\n- Always use HTTPS in production.\n- Store secrets (like JWT secret) securely (environment variables or secret managers).\n- Use strong passwords and consider using a stronger password hashing algorithm (e.g., BCrypt) for","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffajarnugraha37%2Fdotnet-xunit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffajarnugraha37%2Fdotnet-xunit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffajarnugraha37%2Fdotnet-xunit/lists"}