task_id: “1.13” title: “Dependency Injection” status: “pending” priority: “high” estimated_effort: “medium” created: “2025-07-24” assigned_to: “pair” related_rfds: “RFD 004”
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 injectioncmd/web/handlers.go- Update to use injected dependencies- Future: Add interfaces for external services (database, email)
Dependency Injection Patterns
- Constructor Pattern: Initialize dependencies in main()
- Method Injection: Pass application struct to handler methods
- Interface Segregation: Define interfaces for external services
- 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.
Related Tasks
- 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]