Go - Dependency Injection Patterns
Beginner 10/10
Teacher 10/10
Architect 10/10
Dependency Injection Patterns
Prefer simple constructor injection with interfaces over global state. Consider code generation tools (e.g., Wire) when graphs grow.
Try it: Define an interface for a clock or mailer and inject a fake in tests.
Constructor injection
type Store interface{ GetUser(ctx context.Context, id int) (User, error) }
type Service struct{ st Store }
func NewService(st Store) *Service { return &Service{st: st} }
Interfaces at package boundaries
// in consumer package: define small, focused interfaces
// in provider package: implement with concrete types
Composition root
func main(){
db := openDB()
st := NewDBStore(db)
svc := NewService(st)
startHTTP(svc)
}
Common errors
- Huge interfaces that are hard to mock—prefer small interfaces with one or two methods.
- Global singletons that make testing difficult.
Practice
- Introduce a clock interface and pass a fake clock in tests to control time.
Quick quiz
- Where should interfaces be defined?