Use samber/do for Generics-Based Dependency Injection
mainsamber/do provides type-safe dependency injection using Go generics. It avoids reflection and code generation, ensuring that errors are caught at compile time rather than runtime.
Key features include:
- No code generation: No extra build steps or generated files.
- Strongly typed: Uses Go generics to avoid
interface{}casting. - Built-in lifecycle: Automatically handles health checks and graceful shutdowns for services implementing the
Shutdownerinterface. - Container cloning: Allows creating isolated containers from production configurations for testing.
- Package system: Enables organizing services by domain.
// Register services with providers
injector := do.New()
do.Provide(injector, func(i do.Injector) (*UserService, error) {
db := do.MustInvoke[*Database](i)
return NewUserService(db), nil
})
// Invoke services (lazy — created on demand)
svc := do.MustInvoke[*UserService](injector)
// Graceful shutdown — all services implementing Shutdowner are closed
injector.ShutdownOnSignalsWithContext(ctx, os.Interrupt)