# Golang Samber Do > Inyección de dependencias en Golang con samber/do: contenedores de servicios, gestión de ciclo de vida, scopes, health checks, apagado ordenado y organización en módulos. Fuente: https://skillsagentes.com/skills/samber/cc-skills-golang/golang-samber-do Markdown: https://skillsagentes.com/skills/samber/cc-skills-golang/golang-samber-do.md Repositorio: https://github.com/samber/cc-skills-golang Autor: samber Licencia: MIT Actualizado: hace 22 días Coste de contexto: 86 tok instalada, 2.3k tok al activarse, 6.9k tok con todos los archivos del bundle Bundle: 4 archivos, 27 KB Permisos que pide: read edit write glob grep bash(go:*) bash(golangci-lint:*) bash(git:*) agent webfetch mcp__context7__resolve-library-id mcp__context7__query-docs bash(godig:*) bash(gopls:*) lsp mcp__gopls__* ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent claude-code # Cursor npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent cursor # Codex npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent codex # Gemini CLI npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent gemini # Windsurf npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent windsurf # Cline npx -y skills add samber/cc-skills-golang --skill golang-samber-do --agent cline ``` ## Qué hace - Configura contenedores de inyección de dependencias con samber/do v2: registro de servicios, invocación y organización en módulos - Aplica patrones de composition root, tipos de servicio (Lazy, Eager, Transient, Value) y aliasing implícito de interfaces - Refactoriza inyección manual por constructor hacia un contenedor DI con do.Provide y do.Invoke - Organiza registros de servicios en do.Package() por módulo (infraestructura, repositorio, servicio, transporte) ## Cuándo usarla - El código importa github.com/samber/do o github.com/samber/do/v2 - Se está adoptando o usando samber/do para DI - Se refactoriza inyección manual por constructor hacia un contenedor DI ## Cuándo no - No usar la v1 de la librería, instalar en su lugar github.com/samber/do/v2 ## Qué la activa - "Configura un contenedor de DI con samber/do/v2 para mi aplicación Go" - "Refactoriza esta inyección manual de constructores a samber/do" - "Organiza mis servicios en do.Package() por módulo" - "Cómo registro un servicio named con samber/do" ## Antes de instalar - Requiere Go 1.18+ (por generics) y el binario go instalado; usar github.com/samber/do/v2, no la v1. ## Archivos - SKILL.md — 9 KB - evals/evals.json — 12 KB - references/advanced.md — 5 KB - references/testing.md — 1 KB ## SKILL.md Reproducido tal cual desde samber/cc-skills-golang bajo MIT. Esta sección es el documento original y está en inglés. **Persona:** You are a Go architect setting up dependency injection. You keep the container at the composition root, depend on interfaces not concrete types, and treat provider errors as first-class failures. # Using samber/do for Dependency Injection in Go Type-safe dependency injection toolkit for Go based on Go 1.18+ generics. **Official Resources:** - [pkg.go.dev/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2) - [do.samber.dev](https://do.samber.dev) - [github.com/samber/do/v2](https://github.com/samber/do) This skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev. DO NOT USE v1 OF THIS LIBRARY. INSTALL v2 INSTEAD: ```bash go get -u github.com/samber/do/v2 ``` ## Core Concepts ### The Injector (Container) ```go import "github.com/samber/do/v2" injector := do.New() ``` ### Service Types - **Lazy** (default): Created when first requested - **Eager**: Created immediately when the container starts - **Transient**: New instance created on every request - **Value**: Pre-created value, no instantiation ### Provider Functions Services MUST be registered via provider functions: ```go type Provider[T any] func(i Injector) (T, error) ``` ## Basic Usage ### 1. Define and Register Services Follow "Accept Interfaces, Return Structs": ```go // Register a service (lazy by default) do.Provide(injector, func(i do.Injector) (Database, error) { return &PostgreSQLDatabase{connString: "postgres://..."}, nil }) // Register a pre-created value do.ProvideValue(injector, &Config{Port: 8080}) // Register a transient service (new instance each time) do.ProvideTransient(injector, func(i do.Injector) (*Logger, error) { return &Logger{}, nil }) // Register an eager service (created immediately at startup) do.ProvideValue(injector, &Config{Port: 8080}) ``` ### 2. Invoke Services The container MUST only be accessed at the composition root: ```go // Invoke with error handling — reserve for call sites outside the DI graph // (e.g. an HTTP handler that must degrade gracefully instead of crashing) db, err := do.Invoke[Database](injector) // MustInvoke panics on error — preferred in providers, recovered by do.Invoke on the parent call db := do.MustInvoke[Database](injector) ``` Inside a provider function, always use `do.MustInvoke` (or `MustInvokeAs`/`MustInvokeNamed`/`MustInvokeStruct`) rather than the error-returning variant. A provider already returns `(T, error)`, so propagating a dependency failure with `do.Invoke` costs an extra `if err != nil { return nil, err }` on every call. `do.MustInvoke` panics instead, but samber/do correctly catches and recovers that panic at the enclosing `Invoke` call and converts it back into a regular error — this recover happens inside the library itself, not in caller code, so `MustInvoke` is safe to use inside providers. The failure still surfaces as an error at the composition root, just without the manual boilerplate in every provider. ### 3. Service Dependencies ```go func NewUserService(i do.Injector) (UserService, error) { db := do.MustInvoke[Database](i) cache := do.MustInvoke[Cache](i) return &userService{db: db, cache: cache}, nil } do.Provide(injector, NewUserService) ``` ### 4. Implicit Aliasing (Preferred) Register a concrete type and invoke as an interface without explicit aliasing: ```go // Register concrete type do.Provide(injector, func(i do.Injector) (*PostgreSQLDatabase, error) { return &PostgreSQLDatabase{}, nil }) // Invoke directly as interface (implicit aliasing) db := do.MustInvokeAs[Database](injector) ``` ### 5. Named Services Register multiple services of the same type: ```go do.ProvideNamed(injector, "primary-db", func(i do.Injector) (*Database, error) { return &Database{URL: "postgres://primary..."}, nil }) mainDB := do.MustInvokeNamed[*Database](injector, "primary-db") ``` ## Package Organization Use `do.Package()` to organize service registration by module: ```go // infrastructure/package.go var Package = do.Package( do.Lazy(func(i do.Injector) (*postgres.DB, error) { cfg := do.MustInvoke[*Config](i) return postgres.Connect(cfg.DatabaseURL) }), do.Lazy(func(i do.Injector) (*redis.Client, error) { cfg := do.MustInvoke[*Config](i) return redis.NewClient(cfg.RedisURL), nil }), ) // main.go injector := do.New(infrastructure.Package, service.Package) ``` ## Full Application Setup ```go func main() { injector := do.New( infrastructure.Package, repository.Package, service.Package, transport.Package, ) server := do.MustInvoke[*http.Server](injector) go server.ListenAndServe() _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt) } ``` ## Best Practices 1. Depend on interfaces, not concrete types — lets you swap implementations in tests without touching production code 2. Each service should have one job — services with multiple responsibilities are harder to test and harder to replace 3. Keep dependency trees shallow — chains beyond 3-4 levels make initialization order fragile and errors harder to trace 4. Handle errors in provider functions — a silently failing provider creates a broken service that crashes later in unexpected places 5. Use scopes to organize services by lifecycle — request-scoped services prevent leaks, global services prevent redundant initialization 6. Use `do.MustInvoke*` inside provider functions instead of `do.Invoke*` — samber/do correctly catches and recovers the panic at the outer `Invoke` call, turning it back into a returned error, so it's safe to use inside providers and you get the same error propagation without the boilerplate For scopes, lifecycle management, struct injection, and debugging, see [Advanced Usage](./references/advanced.md). For testing patterns (cloning, overrides, mocks), see [Testing](./references/testing.md). ## Quick Reference ### Registration | Function | Purpose | | ------------------------------- | -------------------------------- | | `do.Provide[T]()` | Register lazy service (default) | | `do.ProvideNamed[T]()` | Register named lazy service | | `do.ProvideValue[T]()` | Register pre-created value | | `do.ProvideNamedValue[T]()` | Register named value | | `do.ProvideTransient[T]()` | Register new instance each time | | `do.ProvideNamedTransient[T]()` | Register named transient service | | `do.Package()` | Group service registrations | ### Invocation | Function | Purpose | | -------------------------- | ----------------------------------------- | | `do.Invoke[T]()` | Get service (with error) | | `do.InvokeNamed[T]()` | Get named service | | `do.InvokeAs[T]()` | Get first service matching interface | | `do.InvokeStruct[T]()` | Inject into struct fields using tags | | `do.MustInvoke[T]()` | Get service (panic on error) | | `do.MustInvokeNamed[T]()` | Get named service (panic on error) | | `do.MustInvokeAs[T]()` | Get service by interface (panic on error) | | `do.MustInvokeStruct[T]()` | Inject into struct (panic on error) | ## Cross-References - → See `samber/cc-skills-golang@golang-dependency-injection` skill for DI concepts, comparison, and when to adopt a DI library - → See `samber/cc-skills-golang@golang-structs-interfaces` skill for interface design patterns - → See `samber/cc-skills-golang@golang-testing` skill for general testing patterns ## Dónde encaja - Categoría: [Herramientas para desarrolladores](https://skillsagentes.com/categorias/herramientas-desarrollo.md) — Skills que cambian cómo tu agente escribe, revisa y despliega código. - Creador: [samber](https://skillsagentes.com/creators/samber.md) — 0 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [Golang Lint](https://skillsagentes.com/skills/samber/cc-skills-golang/golang-lint.md): Buenas prácticas de linting y configuración de golangci-lint para proyectos Golang: ejecutar linters, configurar .golangci.yml, suprimir avisos con nolint, interpretar salidas y elegir linters. - [Golang How To](https://skillsagentes.com/skills/samber/cc-skills-golang/golang-how-to.md): Orquestador de skills de Golang, siempre activo en cualquier tarea de código, revisión, debug o setup: carga las skills más relevantes de samber/cc-skills-golang, a menudo varias a la vez. - [Golang Benchmark](https://skillsagentes.com/skills/samber/cc-skills-golang/golang-benchmark.md): Benchmarking, profiling y medición de rendimiento en Golang: escribir y comparar benchmarks, perfilar con pprof, analizar con benchstat y detectar regresiones en CI. - [Golang Testing](https://skillsagentes.com/skills/samber/cc-skills-golang/golang-testing.md): Tests de Golang listos para producción: table-driven, suites y mocks con testify, tests paralelos, fuzzing, fixtures, detección de fugas de goroutines con goleak, snapshot testing, cobertura, tests de integración. - [Golang Performance](https://skillsagentes.com/skills/samber/cc-skills-golang/golang-performance.md): Patrones y metodología de optimización de rendimiento en Golang: si hay cuello de botella X, aplica el patrón Y, una vez que profiling o benchmarks ya lo identificaron. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)