task/1.15
Raw Download raw file

Task 1.13: Dependency Injection

Summary

Implement proper dependency injection pattern for buylater.email to improve testability, maintainability, and separation of concerns by cleanly managing application dependencies.

Motivation

Following Let’s Go Chapter 3.3, we need to formalize our dependency injection approach to make the application more modular, testable, and maintainable. This builds on our application struct pattern to properly inject dependencies throughout the system.

Acceptance Criteria

  • Refactor application struct to be the central dependency container
  • Implement dependency injection for all handlers
  • Create interfaces for external dependencies (future database, email service)
  • Update handler methods to receive dependencies through application struct
  • Remove global variables and direct dependency access
  • Implement clean dependency initialization in main.go
  • Prepare structure for future database and email service injection
  • Add dependency validation and initialization checks
  • Document dependency injection patterns used

Technical Requirements

Application Structure

type application struct {
    config config
    logger struct {
        info  *log.Logger
        error *log.Logger
    }
    // Future dependencies will be added here:
    // db     database.DB
    // mailer mailer.Service
}

Implementation Details

  • Make application struct the single source of dependencies
  • Pass application instance to all handlers that need dependencies
  • Create initialization functions for complex dependencies
  • Implement clean separation between dependency creation and usage
  • Add validation for required dependencies
  • Prepare interfaces for future external services

Dependencies

  • Task 1.12 completed (structured logging system)

Testing Strategy

Unit Tests

  • Test dependency initialization and validation
  • Verify proper dependency injection throughout handlers
  • Test application struct methods

Integration Tests

  • All handlers work with injected dependencies
  • Dependency initialization is robust
  • Application starts correctly with all dependencies

Manual Testing

  • Application starts without dependency errors
  • All handlers function correctly with injected dependencies
  • Logging works through injected loggers
  • Configuration is properly available throughout app

Definition of Done

  • All acceptance criteria met
  • All specified tests pass
  • Code follows project conventions (go fmt, go vet)
  • Clean dependency injection pattern implemented
  • No global variables or direct dependency access
  • Dependencies are properly initialized and validated
  • Human verification completed successfully
  • Git commit created with proper message format

Implementation Notes

Approach

Formalize the dependency injection pattern started in Task 1.10 by making the application struct a proper dependency container and ensuring all dependencies flow cleanly through the application.

Key Files to Modify

  • cmd/web/main.go - Dependency initialization and injection
  • cmd/web/handlers.go - Update to use injected dependencies
  • Future: Add interfaces for external services (database, email)

Dependency Injection Patterns

  1. Constructor Pattern: Initialize dependencies in main()
  2. Method Injection: Pass application struct to handler methods
  3. Interface Segregation: Define interfaces for external services
  4. Dependency Container: Application struct holds all dependencies

Current Dependencies to Inject

  • Configuration settings
  • Structured loggers (info, error)
  • Future: Database connection, email service, template cache

Potential Risks

  • Over-engineering simple dependency needs
  • Circular dependency issues
  • Complex initialization order requirements

Success Metrics

Clean, maintainable dependency injection system that makes buylater.email more testable and modular while preparing for future service integrations.

  • Blocks: Database integration, email service, testing improvements
  • Blocked by: Task 3.2 (needs structured logging)
  • Related: Testing, modularity, and future service integrations

Implementation Log

Implementation details will be recorded here during development.


Final Verification

Human Tester: [Name]
Date Completed: [YYYY-MM-DD]
Verification Result: [Pass/Fail]
Notes: [Any issues found or additional observations]