ASP.NET Core Web API with 3-Tier Architecture and Iterator Pattern

Introduction

This project demonstrates an ASP.NET Core Web API with a 3-tier architecture featuring CRUD operations for managing a collection of library books. The application is designed with a data access layer (DAL) employing the Iterator Design Pattern to encapsulate the iteration logic for the library book collection. The solution includes a data layer defining the LibraryBook model, a data access layer with a LibraryBookRepository implementing CRUD operations and the Iterator pattern, and a business logic layer (BLL) with a LibraryBookService. The API controllers in the presentation layer enable HTTP endpoints for adding, updating, deleting, and retrieving library books.

Implementing a complete CRUD functionality with the Iterator Design Pattern in an ASP.NET Core Web API with a 3-tier architecture involves several steps. I'll provide a simplified example to guide you through the process.

Step 1. Define the Model (Data Layer)

// Sardar Mudassar Ali Khan
// Models/LibraryBook.cs
public class LibraryBook
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
}

Step 2. Create Data Access Layer (DAL)

// DataAccessLayer/LibraryBookRepository.cs
using System.Collections;
using System.Collections.Generic;

public interface ILibraryBookIterator
{
    LibraryBook Next();
    bool HasNext();
}

public interface ILibraryBookRepository : IEnumerable<LibraryBook>
{
    void Add(LibraryBook book);
    void Update(LibraryBook book);
    void Delete(int id);
    LibraryBook GetById(int id);
    ILibraryBookIterator CreateIterator();
}

public class LibraryBookRepositoryIterator: ILibraryBookIterator
{
    private readonly List<LibraryBook> books;
    private int position = 0;

    public LibraryBookRepositoryIterator(List<LibraryBook> books)
    {
        this.books = books;
    }

    public LibraryBook Next()
    {
        var book = books[position];
        position++;
        return book;
    }

    public bool HasNext()
    {
        return position < books.Count;
    }
}

public class LibraryBookRepository: ILibraryBookRepository
{
    private List<LibraryBook> books;

    public LibraryBookRepository()
    {
        books = new List<LibraryBook>();
    }

    public void Add(LibraryBook book)
    {
        books.Add(book);
    }

    public void Update(LibraryBook book)
    {
        var existingBook = GetById(book.Id);
        if (existingBook != null)
        {
            // Update properties
            existingBook.Title = book.Title;
            existingBook.Author = book.Author;
            // Update other properties as needed
        }
    }

    public void Delete(int id)
    {
        var bookToRemove = GetById(id);
        if (bookToRemove != null)
        {
            books.Remove(bookToRemove);
        }
    }

    public LibraryBook GetById(int id)
    {
        return books.FirstOrDefault(b => b.Id == id);
    }

    public IEnumerator<LibraryBook> GetEnumerator()
    {
        return books.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public ILibraryBookIterator CreateIterator()
    {
        return new LibraryBookRepositoryIterator(books);
    }
}

Step 3. Implement Business Logic Layer (BLL)

// Sardar Mudassar Ali Khan
// BusinessLogicLayer/LibraryBookService.cs
public class LibraryBookService
{
    private readonly ILibraryBookRepository book repository;

    public LibraryBookService(ILibraryBookRepository bookRepository)
    {
        this.bookRepository = bookRepository;
    }

    public void AddBook(LibraryBook book)
    {
        bookRepository.Add(book);
    }

    public void UpdateBook(LibraryBook book)
    {
        bookRepository.Update(book);
    }

    public void DeleteBook(int id)
    {
        bookRepository.Delete(id);
    }

    public LibraryBook GetBookById(int id)
    {
        return bookRepository.GetById(id);
    }

    public IEnumerable<LibraryBook> GetAllBooks()
    {
        return bookRepository;
    }
}

Step 4. Implement API Controllers (Presentation Layer)

// Sardar Mudassar Ali Khan
// Controllers/LibraryBookController.cs
[ApiController]
[Route("api/[controller]")]
public class LibraryBookController : ControllerBase
{
    private readonly LibraryBookService bookService;

    public LibraryBookController(LibraryBookService bookService)
    {
        this.bookService = bookService;
    }

    [HttpPost]
    public IActionResult AddBook([FromBody] LibraryBook book)
    {
        bookService.AddBook(book);
        return Ok();
    }

    [HttpPut]
    public IActionResult UpdateBook([FromBody] LibraryBook book)
    {
        bookService.UpdateBook(book);
        return Ok();
    }

    [HttpDelete("{id}")]
    public IActionResult DeleteBook(int id)
    {
        bookService.DeleteBook(id);
        return Ok();
    }

    [HttpGet("{id}")]
    public IActionResult GetBookById(int id)
    {
        var book = bookService.GetBookById(id);
        return Ok(book);
    }

    [HttpGet]
    public IActionResult GetAllBooks()
    {
        var books = bookService.GetAllBooks();
        return Ok(books);
    }
}

Step 5. Dependency Injection (Startup.cs)

// Sardar Mudassar Ali Khan
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // Other configurations

    services.AddSingleton<ILibraryBookRepository, LibraryBookRepository>();
    services.AddScoped<LibraryBookService>();
    services.AddControllers();
}

Conclusion

In conclusion, we've implemented a simple ASP.NET Core Web API with a 3-tier architecture (Data Access Layer, Business Logic Layer, and Presentation Layer) for managing a collection of library books. We incorporated the Iterator Design Pattern to encapsulate the iteration logic for the collection of LibraryBook objects.

Key steps in the implementation

1. Model Definition

  • Defined the LibraryBook model to represent the data structure.

2. Data Access Layer (DAL)

  • Created the ILibraryBookIterator and ILibraryBookRepository interfaces.
  • Implemented the LibraryBookRepositoryIterator class for the iterator pattern.
  • Updated the LibraryBookRepository class to include the iterator pattern using the CreateIterator method.

3. Business Logic Layer (BLL)

  • Implemented the LibraryBookService class, which serves as an intermediary between the DAL and the API controllers.

4. API Controllers (Presentation Layer)

  • Created the LibraryBookController class to handle HTTP requests and interact with the LibraryBookService

5. Dependency Injection (Startup. cs)

  • Configured dependency injection for the ILibraryBookRepository and LibraryBookService in the Startup.cs file.

This implementation provides a foundation for a scalable and maintainable application, with a separation of concerns between different layers. The Iterator Design Pattern enhances the flexibility and extensibility of the code by encapsulating the iteration logic, allowing for easier changes in the future.


Similar Articles