{"id":"7a81ded7-8139-450e-afe7-f4a95acf46d9","shortId":"6K9bku","kind":"skill","title":"golang-samber-do","tagline":"Implements dependency injection in Golang using samber/do. Apply this skill when working with dependency injection, setting up service containers, managing service lifecycles, or when you see code using github.com/samber/do/v2. Also use when refactoring manual dependency injectio","description":"**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.\n\n# Using samber/do for Dependency Injection in Go\n\nType-safe dependency injection toolkit for Go based on Go 1.18+ generics.\n\n**Official Resources:**\n\n- [pkg.go.dev/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2)\n- [do.samber.dev](https://do.samber.dev)\n- [github.com/samber/do/v2](https://github.com/samber/do)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.\n\nDO NOT USE v1 OF THIS LIBRARY. INSTALL v2 INSTEAD:\n\n```bash\ngo get -u github.com/samber/do/v2\n```\n\n## Core Concepts\n\n### The Injector (Container)\n\n```go\nimport \"github.com/samber/do/v2\"\n\ninjector := do.New()\n```\n\n### Service Types\n\n- **Lazy** (default): Created when first requested\n- **Eager**: Created immediately when the container starts\n- **Transient**: New instance created on every request\n- **Value**: Pre-created value, no instantiation\n\n### Provider Functions\n\nServices MUST be registered via provider functions:\n\n```go\ntype Provider[T any] func(i Injector) (T, error)\n```\n\n## Basic Usage\n\n### 1. Define and Register Services\n\nFollow \"Accept Interfaces, Return Structs\":\n\n```go\n// Register a service (lazy by default)\ndo.Provide(injector, func(i do.Injector) (Database, error) {\n    return &PostgreSQLDatabase{connString: \"postgres://...\"}, nil\n})\n\n// Register a pre-created value\ndo.ProvideValue(injector, &Config{Port: 8080})\n\n// Register a transient service (new instance each time)\ndo.ProvideTransient(injector, func(i do.Injector) (*Logger, error) {\n    return &Logger{}, nil\n})\n\n// Register an eager service (created immediately)\ndo.Provide(injector, do.Eager(&Config{Port: 8080}))\n```\n\n### 2. Invoke Services\n\nThe container MUST only be accessed at the composition root:\n\n```go\n// Invoke with error handling\ndb, err := do.Invoke[Database](injector)\n\n// MustInvoke panics on error (use when confident service exists)\ndb := do.MustInvoke[Database](injector)\n```\n\n### 3. Service Dependencies\n\n```go\nfunc NewUserService(i do.Injector) (UserService, error) {\n    db := do.MustInvoke[Database](i)\n    cache := do.MustInvoke[Cache](i)\n    return &userService{db: db, cache: cache}, nil\n}\n\ndo.Provide(injector, NewUserService)\n```\n\n### 4. Implicit Aliasing (Preferred)\n\nRegister a concrete type and invoke as an interface without explicit aliasing:\n\n```go\n// Register concrete type\ndo.Provide(injector, func(i do.Injector) (*PostgreSQLDatabase, error) {\n    return &PostgreSQLDatabase{}, nil\n})\n\n// Invoke directly as interface (implicit aliasing)\ndb := do.MustInvokeAs[Database](injector)\n```\n\n### 5. Named Services\n\nRegister multiple services of the same type:\n\n```go\ndo.ProvideNamed(injector, \"primary-db\", func(i do.Injector) (*Database, error) {\n    return &Database{URL: \"postgres://primary...\"}, nil\n})\n\nmainDB := do.MustInvokeNamed[*Database](injector, \"primary-db\")\n```\n\n## Package Organization\n\nUse `do.Package()` to organize service registration by module:\n\n```go\n// infrastructure/package.go\nvar Package = do.Package(\n    do.Lazy(func(i do.Injector) (*postgres.DB, error) {\n        cfg := do.MustInvoke[*Config](i)\n        return postgres.Connect(cfg.DatabaseURL)\n    }),\n    do.Lazy(func(i do.Injector) (*redis.Client, error) {\n        cfg := do.MustInvoke[*Config](i)\n        return redis.NewClient(cfg.RedisURL), nil\n    }),\n)\n\n// main.go\ninjector := do.New(infrastructure.Package, service.Package)\n```\n\n## Full Application Setup\n\n```go\nfunc main() {\n    injector := do.New(\n        infrastructure.Package,\n        repository.Package,\n        service.Package,\n        transport.Package,\n    )\n\n    server := do.MustInvoke[*http.Server](injector)\n    go server.ListenAndServe()\n\n    _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)\n}\n```\n\n## Best Practices\n\n1. Depend on interfaces, not concrete types — lets you swap implementations in tests without touching production code\n2. Each service should have one job — services with multiple responsibilities are harder to test and harder to replace\n3. Keep dependency trees shallow — chains beyond 3-4 levels make initialization order fragile and errors harder to trace\n4. Handle errors in provider functions — a silently failing provider creates a broken service that crashes later in unexpected places\n5. Use scopes to organize services by lifecycle — request-scoped services prevent leaks, global services prevent redundant initialization\n\nFor scopes, lifecycle management, struct injection, and debugging, see [Advanced Usage](./references/advanced.md).\n\nFor testing patterns (cloning, overrides, mocks), see [Testing](./references/testing.md).\n\n## Quick Reference\n\n### Registration\n\n| Function                        | Purpose                          |\n| ------------------------------- | -------------------------------- |\n| `do.Provide[T]()`               | Register lazy service (default)  |\n| `do.ProvideNamed[T]()`          | Register named lazy service      |\n| `do.ProvideValue[T]()`          | Register pre-created value       |\n| `do.ProvideNamedValue[T]()`     | Register named value             |\n| `do.ProvideTransient[T]()`      | Register new instance each time  |\n| `do.ProvideNamedTransient[T]()` | Register named transient service |\n| `do.Package()`                  | Group service registrations      |\n\n### Invocation\n\n| Function                   | Purpose                                   |\n| -------------------------- | ----------------------------------------- |\n| `do.Invoke[T]()`           | Get service (with error)                  |\n| `do.InvokeNamed[T]()`      | Get named service                         |\n| `do.InvokeAs[T]()`         | Get first service matching interface      |\n| `do.InvokeStruct[T]()`     | Inject into struct fields using tags      |\n| `do.MustInvoke[T]()`       | Get service (panic on error)              |\n| `do.MustInvokeNamed[T]()`  | Get named service (panic on error)        |\n| `do.MustInvokeAs[T]()`     | Get service by interface (panic on error) |\n| `do.MustInvokeStruct[T]()` | Inject into struct (panic on error)       |\n\n## Cross-References\n\n- → See `samber/cc-skills-golang@golang-dependency-injection` skill for DI concepts, comparison, and when to adopt a DI library\n- → See `samber/cc-skills-golang@golang-structs-interfaces` skill for interface design patterns\n- → See `samber/cc-skills-golang@golang-testing` skill for general testing patterns","tags":["golang","samber","skills","agent","agent-skills","antigravity","claude","claude-code","code","codex","coding","copilot"],"capabilities":["skill","source-samber","skill-golang-samber-do","topic-agent","topic-agent-skills","topic-antigravity","topic-claude","topic-claude-code","topic-code","topic-codex","topic-coding","topic-copilot","topic-cursor","topic-gemini","topic-gemini-cli-extension"],"categories":["cc-skills-golang"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/samber/cc-skills-golang/golang-samber-do","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add samber/cc-skills-golang","source_repo":"https://github.com/samber/cc-skills-golang","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 1725 github stars · SKILL.md body (6,622 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:02.133Z","embedding":null,"createdAt":"2026-04-18T20:32:43.751Z","updatedAt":"2026-05-18T18:53:02.133Z","lastSeenAt":"2026-05-18T18:53:02.133Z","tsv":"'-4':528 '/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2)':100 '/references/advanced.md':589 '/references/testing.md':598 '/samber/do/v2':145,155 '/samber/do/v2.':35 '/samber/do/v2](https://github.com/samber/do)':105 '1':208,484 '1.18':94 '2':277,501 '3':313,520,527 '4':341,539 '5':381,559 '8080':246,276 'accept':214 'access':285 'adopt':723 'advanc':587 'alias':343,356,376 'also':36 'appli':12 'applic':462 'architect':48 'base':91 'bash':139 'basic':206 'best':482 'beyond':526 'broken':551 'cach':327,329,335,336 'cfg':435,448 'cfg.databaseurl':441 'cfg.redisurl':454 'chain':525 'class':74 'clone':593 'code':31,117,500 'comparison':719 'composit':59,288 'concept':147,718 'concret':65,347,359,489 'confid':306 'config':244,274,437,450 'connstr':234 'contain':23,56,150,171,281 'context.background':480 'context7':122 'core':146 'crash':554 'creat':162,167,176,183,240,269,549,621 'cross':707 'cross-refer':706 'databas':230,298,311,325,379,400,403,409 'db':295,309,323,333,334,377,396,413 'debug':585 'default':161,224,609 'defin':209 'depend':6,18,41,51,61,79,86,315,485,522,713 'design':736 'di':717,725 'direct':372 'discover':127 'do.eager':273 'do.injector':229,259,320,365,399,432,445 'do.invoke':297,648 'do.invokeas':659 'do.invokenamed':654 'do.invokestruct':666 'do.lazy':429,442 'do.mustinvoke':310,324,328,436,449,474,674 'do.mustinvokeas':378,689 'do.mustinvokenamed':408,681 'do.mustinvokestruct':698 'do.new':157,458,468 'do.package':417,428,641 'do.provide':225,271,338,361,604 'do.providenamed':392,610 'do.providenamedtransient':635 'do.providenamedvalue':623 'do.providetransient':255,628 'do.providevalue':242,616 'do.samber.dev':101,102 'document':115 'eager':166,267 'err':296 'error':70,205,231,261,293,303,322,367,401,434,447,535,541,653,680,688,697,705 'everi':178 'exampl':118 'exhaust':110 'exist':308 'explicit':355 'fail':547 'failur':75 'field':671 'first':73,164,662 'first-class':72 'follow':213 'fragil':533 'full':461 'func':201,227,257,317,363,397,430,443,465 'function':188,195,544,602,646 'general':745 'generic':95 'get':141,650,656,661,676,683,691 'github.com':34,104,144,154 'github.com/samber/do/v2':143,153 'github.com/samber/do/v2.':33 'github.com/samber/do/v2](https://github.com/samber/do)':103 'global':573 'go':47,82,90,93,140,151,196,218,290,316,357,391,424,464,477 'golang':2,9,712,730,741 'golang-dependency-inject':711 'golang-samber-do':1 'golang-structs-interfac':729 'golang-test':740 'group':642 'handl':294,540 'harder':513,517,536 'help':124 'http.server':475 'immedi':168,270 'implement':5,494 'implicit':342,375 'import':152 'inform':121 'infrastructure.package':459,469 'infrastructure/package.go':425 'initi':531,577 'inject':7,19,52,80,87,583,668,700,714 'injectio':42 'injector':149,156,203,226,243,256,272,299,312,339,362,380,393,410,457,467,476 'injector.shutdownonsignalswithcontext':479 'instal':136 'instanc':175,252,632 'instanti':186 'instead':138 'interfac':63,215,353,374,487,665,694,732,735 'invoc':645 'invok':278,291,350,371 'job':507 'keep':54,521 'later':555 'lazi':160,222,607,614 'leak':572 'let':491 'level':529 'librari':114,135,726 'lifecycl':26,566,580 'logger':260,263 'main':466 'main.go':456 'maindb':407 'make':530 'manag':24,581 'manual':40 'match':664 'mock':595 'modul':423 'multipl':385,510 'must':190,282 'mustinvok':300 'name':382,613,626,638,657,684 'new':174,251,631 'newuserservic':318,340 'nil':235,264,337,370,406,455 'offici':96 'one':506 'order':532 'organ':415,419,563 'os.interrupt':481 'overrid':594 'packag':414,427 'panic':301,678,686,695,703 'pattern':592,737,747 'persona':43 'pkg.go.dev':99 'pkg.go.dev/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2)':98 'place':558 'platform':128 'pleas':111 'port':245,275 'postgres.connect':440 'postgres.db':433 'postgresqldatabas':233,366,369 'practic':483 'pre':182,239,620 'pre-creat':181,238,619 'prefer':344 'prevent':571,575 'primari':395,405,412 'primary-db':394,411 'product':499 'provid':69,187,194,198,543,548 'purpos':603,647 'quick':599 'redis.client':446 'redis.newclient':453 'redund':576 'refactor':39 'refer':112,600,708 'regist':192,211,219,236,247,265,345,358,384,606,612,618,625,630,637 'registr':421,601,644 'replac':519 'repository.package':470 'request':165,179,568 'request-scop':567 'resourc':97 'respons':511 'return':216,232,262,331,368,402,439,452 'root':60,289 'safe':85 'samber':3 'samber/cc-skills-golang':710,728,739 'samber/do':11,77 'scope':561,569,579 'see':30,586,596,709,727,738 'server':473 'server.listenandserve':478 'servic':22,25,158,189,212,221,250,268,279,307,314,383,386,420,503,508,552,564,570,574,608,615,640,643,651,658,663,677,685,692 'service.package':460,471 'set':20,49 'setup':463 'shallow':524 'silent':546 'skill':14,107,715,733,743 'skill-golang-samber-do' 'source-samber' 'start':172 'struct':217,582,670,702,731 'swap':493 'tag':673 'test':496,515,591,597,742,746 'time':254,634 'toolkit':88 'topic-agent' 'topic-agent-skills' 'topic-antigravity' 'topic-claude' 'topic-claude-code' 'topic-code' 'topic-codex' 'topic-coding' 'topic-copilot' 'topic-cursor' 'topic-gemini' 'topic-gemini-cli-extension' 'touch':498 'trace':538 'transient':173,249,639 'transport.package':472 'treat':68 'tree':523 'type':66,84,159,197,348,360,390,490 'type-saf':83 'u':142 'unexpect':557 'url':404 'usag':207,588 'use':10,32,37,76,131,304,416,560,672 'userservic':321,332 'v1':132 'v2':137 'valu':180,184,241,622,627 'var':426 'via':193 'without':354,497 'work':16","prices":[{"id":"3c993e99-7c80-42e9-a7ca-5999155695f8","listingId":"7a81ded7-8139-450e-afe7-f4a95acf46d9","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"samber","category":"cc-skills-golang","install_from":"skills.sh"},"createdAt":"2026-04-18T20:32:43.751Z"}],"sources":[{"listingId":"7a81ded7-8139-450e-afe7-f4a95acf46d9","source":"github","sourceId":"samber/cc-skills-golang/golang-samber-do","sourceUrl":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-samber-do","isPrimary":false,"firstSeenAt":"2026-04-18T21:55:17.952Z","lastSeenAt":"2026-05-18T18:53:02.133Z"},{"listingId":"7a81ded7-8139-450e-afe7-f4a95acf46d9","source":"skills_sh","sourceId":"samber/cc-skills-golang/golang-samber-do","sourceUrl":"https://skills.sh/samber/cc-skills-golang/golang-samber-do","isPrimary":true,"firstSeenAt":"2026-04-18T20:32:43.751Z","lastSeenAt":"2026-05-07T22:40:28.322Z"}],"details":{"listingId":"7a81ded7-8139-450e-afe7-f4a95acf46d9","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"samber","slug":"golang-samber-do","github":{"repo":"samber/cc-skills-golang","stars":1725,"topics":["agent","agent-skills","ai","antigravity","claude","claude-code","code","codex","coding","copilot","cursor","gemini","gemini-cli-extension","openclaw","opencode","plugin","skills","skillsmp","vibe-coding"],"license":"mit","html_url":"https://github.com/samber/cc-skills-golang","pushed_at":"2026-05-18T17:36:00Z","description":"🧑‍🎨 A collection of Golang agentic skills that works","skill_md_sha":"b62373856ad5456c5b83839a7da5226dea7e072c","skill_md_path":"skills/golang-samber-do/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-samber-do"},"layout":"multi","source":"github","category":"cc-skills-golang","frontmatter":{"name":"golang-samber-do","license":"MIT","description":"Implements dependency injection in Golang using samber/do. Apply this skill when working with dependency injection, setting up service containers, managing service lifecycles, or when you see code using github.com/samber/do/v2. Also use when refactoring manual dependency injection, implementing health checks, graceful shutdown, or organizing services into scopes/modules.","compatibility":"Designed for Claude Code or similar AI coding agents, and for projects using Golang."},"skills_sh_url":"https://skills.sh/samber/cc-skills-golang/golang-samber-do"},"updatedAt":"2026-05-18T18:53:02.133Z"}}