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.