Skip to content

Query database

BookRepo

In controllers and services, we can inject DatabaseContext to call DB. However, that'd make the code difficult to test. Thus, it is common to add a respository or data access layer.

Add a folder Repos and add BookRepo.cs which implements IBookRepo interface and injects DatabaseContext.

csharp
public interface IBookRepo
{
    Task<long> Create(Book book);
}

public class BookRepo : IBookRepo
{
    private readonly DatabaseContext _context;

    public BookRepo(DatabaseContext context)
    {
        _context = context;
    }

    public async Task<long> Create(Book book)
    {
        await _context.Bookings.AddAsync(book);
        await _context.SaveChangesAsync();
        return book.Id;
    }
}


In DependencyConfigurator.cs, add

csharp
public static void RegisterDependencies(this WebApplicationBuilder builder)
{
    RegisterRepos(builder); //register repos before services
    RegisterServices(builder);
}

private static void RegisterRepos(this WebApplicationBuilder builder)
{
    builder.Services.AddScoped<IBookRepo, BookRepo>();
}


In BookService.cs, inject IBookRepo

csharp
public class BookService : IBookService
{
    private readonly ILogger<BookService> _logger;
    private readonly IClock _clock;
    private readonly IBookRepo _bookRepo;

    public BookService(ILogger<BookService> logger, IClock clock, IBookRepo bookRepo) //inject IBookRepo
    {
        _logger = logger;
        _clock = clock;
        _bookRepo = bookRepo;
    }

    public async Task<int> All(CreateBookRequest request)
    {
        return await _bookRepo.All();
    }

    public async Task<int> Create(CreateBookRequest request)
    {
        if (request.PublicationYear < 1900 || request.PublicationYear > _clock.Now.Year)
        {
            throw new ValidationException("Publication Year must be between 1990 and 2025");
        }

        var id = await _bookRepo.Create(new BookModel());
        return id;
    }
}


Test the API.

Released under the MIT License.