LibraryService API relies exclusively on ASP.NET Core’s built-in DI container — no third-party IoC framework is used. Every service is registered inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/marchena96/Paradigma-lab1/llms.txt
Use this file to discover all available pages before exploring further.
Startup.ConfigureServices and resolved through standard constructor injection by the runtime. Controllers, services, and EF Core’s context pool all participate in the same container.
Registered services
| Interface / Type | Implementation | Lifetime | Purpose |
|---|---|---|---|
ILibrariesService | LibrariesService | Transient | CRUD operations on the Libraries table |
IBooksService | BooksService | Transient | CRUD operations on the Books table |
IAuthenticationService | AuthenticationService | Scoped | Validates user credentials and returns a User object |
JwtSettings | — (singleton object bound from config) | Singleton | JWT configuration (Issuer, Audience, SecretKey) bound from appsettings.json |
LibraryContext | — (EF Core DbContext pool) | DbContextPool | EF Core database context; pool size 20, Npgsql retry-on-failure |
Startup.ConfigureServices look like this:
Service interfaces
The DI container binds controllers and other consumers to interfaces, not concrete classes. The full signatures for the two primary service interfaces are:ILibrariesService
IBooksService
IAuthenticationService
Constructor injection examples
LibrariesController — single service dependency
LibrariesController declares one constructor parameter. The runtime resolves ILibrariesService → LibrariesService automatically:
BooksController — two service dependencies
BooksController needs both IBooksService and ILibrariesService (to validate that the parent library exists before operating on its books):
AuthController — configuration singleton + scoped service
AuthController injects the JwtSettings singleton (for token signing) alongside the scoped IAuthenticationService:
Why Transient for services?
LibrariesService and BooksService hold no state of their own beyond a single operation. They receive LibraryContext through constructor injection, perform one or more async database calls, and complete. Because EF Core’s DbContextPool manages context lifetime independently, the services themselves are safe to create and discard on every request — there is no benefit to caching them as scoped or singleton objects, and making them transient avoids any risk of stale change-tracker state leaking across requests.
AuthenticationService is registered as Scoped rather than Transient because it is conceptually tied to the lifetime of a single HTTP request — it validates credentials and returns a User for that request. The current implementation is stateless, but Scoped is the conventional lifetime for services that may in future access per-request state (e.g., IHttpContextAccessor).Idempotency guard
The very first statement insideConfigureServices is a guard that makes the entire method idempotent:
WebApplicationFactory<T> triggers ConfigureServices twice: once when Program.CreateHostBuilder builds the real host, and again when UseStartup<Startup> runs inside the test’s custom WebApplicationFactory. Without the guard, the second invocation would attempt to re-add the JWT Bearer scheme to an already-configured authentication builder, throwing "Scheme already exists: Bearer".
The guard uses JwtSettings as a sentinel because it is the first thing registered in the method. If it is already present in the service collection, the entire configuration block has already run and there is nothing left to do.
This pattern is specific to the classic
Startup-based hosting model. In Minimal API projects the problem does not arise because there is no Startup class to be double-invoked.