Skip to content

C# project demonstrating SOLID design principles, Test-Driven Development (TDD), acceptance testing, and clean code practices

License

Notifications You must be signed in to change notification settings

drm317/CleanCodeTDDSolid

Repository files navigation

Library Management System

A C# project demonstrating SOLID design principles, Test-Driven Development (TDD), acceptance testing, and clean code practices.

Project Structure

LibraryManagement/
├── LibraryManagement.Domain/              # Core business logic
│   ├── Entities/                          # Domain entities
│   ├── Interfaces/                        # Abstractions
│   └── Services/                          # Domain services
├── LibraryManagement.Infrastructure/      # Implementation details
│   ├── Repositories/                      # Data access
│   └── Services/                          # External services
├── LibraryManagement.Application/         # Entry point
├── LibraryManagement.Tests/               # Unit tests
└── LibraryManagement.AcceptanceTests/     # Integration tests

Running the Project

# Run the demo application
dotnet run --project LibraryManagement.Application

# Run unit tests
dotnet test LibraryManagement.Tests

# Run acceptance tests
dotnet test LibraryManagement.AcceptanceTests

# Run all tests
dotnet test

SOLID Principles

1. Single Responsibility Principle (SRP)

Each class has one reason to change:

  • Book (LibraryManagement.Domain/Entities/Book.cs:1) - Manages book state and borrowing rules
  • Member (LibraryManagement.Domain/Entities/Member.cs:1) - Manages member information and borrowing limits
  • BookBorrowingService (LibraryManagement.Domain/Services/BookBorrowingService.cs:1) - Handles borrowing/returning logic
  • OverdueBookService (LibraryManagement.Domain/Services/OverdueBookService.cs:1) - Manages overdue book notifications

2. Open/Closed Principle (OCP)

The system is open for extension but closed for modification:

  • Repository Pattern - New storage implementations can be added without changing existing code
  • Notification Services - New notification types (SMS, push notifications) can be added via INotificationService
  • Date/Time Providers - Different time sources can be injected for testing or different environments

3. Liskov Substitution Principle (LSP)

Derived classes are substitutable for their base classes:

  • Repository Implementations - InMemoryBookRepository can be replaced with database implementations
  • Service Implementations - EmailNotificationService can be replaced with other notification providers
  • Date Providers - SystemDateTimeProvider can be replaced with mock providers for testing

4. Interface Segregation Principle (ISP)

Clients depend only on interfaces they use:

  • IBookRepository (LibraryManagement.Domain/Interfaces/IBookRepository.cs:1) - Focused on book data operations
  • IMemberRepository (LibraryManagement.Domain/Interfaces/IMemberRepository.cs:1) - Focused on member data operations
  • INotificationService (LibraryManagement.Domain/Interfaces/INotificationService.cs:1) - Focused on notifications only
  • IDateTimeProvider (LibraryManagement.Domain/Interfaces/IDateTimeProvider.cs:1) - Minimal interface for time operations

5. Dependency Inversion Principle (DIP)

High-level modules don't depend on low-level modules; both depend on abstractions:

  • Domain Services depend on interfaces, not concrete implementations
  • Application layer composes dependencies through constructor injection
  • Infrastructure implements the interfaces defined in the domain

Test-Driven Development (TDD)

The project follows the Red-Green-Refactor cycle:

Unit Tests

  • Entity Tests (LibraryManagement.Tests/Domain/Entities/) - Test business rules and invariants
  • Service Tests (LibraryManagement.Tests/Domain/Services/) - Test business logic with mocked dependencies

Acceptance Tests

  • Integration Tests (LibraryManagement.AcceptanceTests/LibrarySystemAcceptanceTests.cs:1) - Test complete user scenarios
  • End-to-End Workflows - Verify the system works as a whole

Clean Code Practices

Naming Conventions

  • Descriptive Names - BookBorrowingService, GetOverdueBooksAsync
  • Intention-Revealing - CanBorrowMoreBooks(), IsOverdue()
  • Consistent Terminology - Borrow/Return throughout the codebase

Method Design

  • Small Functions - Each method does one thing well
  • Pure Functions - No side effects where possible
  • Meaningful Parameters - Clear parameter names and types

Error Handling

  • Fail Fast - Validate inputs immediately in constructors
  • Meaningful Exceptions - InvalidOperationException with descriptive messages
  • Guard Clauses - Early returns for invalid conditions

Code Organization

  • Separation of Concerns - Domain, Infrastructure, and Application layers
  • Dependency Direction - Dependencies point inward toward the domain
  • Testable Design - All dependencies are abstracted and injectable

About

C# project demonstrating SOLID design principles, Test-Driven Development (TDD), acceptance testing, and clean code practices

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages