
Golang Dependency Injection
Structure Go services with constructor injection, consumer-side interfaces, and testable wiring instead of globals and init().
Overview
Golang Dependency Injection is an agent skill for the Build phase that teaches constructor-based dependency wiring and consumer-defined interfaces in Go services.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-dependency-injectionWhat is this skill?
- Constructor injection via NewX constructors—no package-level service globals
- Explicit ban on init() for service setup and hidden dependency graphs
- Interfaces defined at the consumer package, not beside PostgreSQL implementations
- Constructors return concrete struct pointers, not interfaces, per Go idioms
- Eval-backed assertions (e.g. UserService + DB + logger scenarios) for agent compliance
- Eval scenarios with numbered assertions (e.g. 1.1–1.5) for constructor and interface rules
Adoption & trust: 3.7k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Go service relies on package-level database vars or init() setup, so tests are brittle and dependencies are invisible at call sites.
Who is it for?
Indie devs adding UserService-style layers, stores, and loggers in Go who want agent-generated code to match production DI discipline.
Skip if: Greenfield experiments in a single-file main with no tests planned, or teams standardized on a specific DI framework not covered in the skill text.
When should I use this skill?
Designing or refactoring Go services that need databases, loggers, or stores with testable constructor injection.
What do I get? / Deliverables
You get constructor-injected services, interfaces owned by consumers, and concrete types from New functions—ready for table-driven tests and incremental refactors.
- Refactored constructors and consumer-side interfaces
- Service code that avoids globals and init() bootstrap
Recommended Skills
Journey fit
Build is the primary shelf because the skill teaches how to compose backend services and dependencies while you implement Go code. Backend subphase matches service construction, stores, loggers, and DI patterns central to APIs and workers.
How it compares
Prefer this procedural Go DI skill over ad-hoc chat snippets that happily use global DB handles and misplaced interfaces.
Common Questions / FAQ
Who is golang-dependency-injection for?
Solo builders and small teams writing Go backends who need testable services without enterprise DI containers.
When should I use golang-dependency-injection?
While building backend packages, designing UserStore or similar boundaries, or refactoring globals before adding PostgreSQL or logging dependencies.
Is golang-dependency-injection safe to install?
It is instructional code-pattern guidance; review the Security Audits panel on this Prism page and your org policies before pulling any third-party skill into CI.
SKILL.md
READMESKILL.md - Golang Dependency Injection
[ { "id": 1, "name": "constructor-injection-not-globals", "description": "Tests that dependencies are injected via constructors, not global variables or init()", "prompt": "I have a UserService that needs a database connection and a logger. What's the best way to set this up in Go? I was thinking of using a package-level var for the database.", "trap": "Without the skill, the model may accept the global variable approach or use init() for setup. The skill explicitly forbids globals and init() for service setup.", "assertions": [ {"id": "1.1", "text": "Uses constructor injection (NewUserService taking dependencies as parameters)"}, {"id": "1.2", "text": "Explicitly advises against package-level variables for service dependencies"}, {"id": "1.3", "text": "Explains why globals are problematic (untestable, hidden dependencies, or coupling)"}, {"id": "1.4", "text": "Does NOT use init() for service initialization"}, {"id": "1.5", "text": "Returns a concrete struct pointer from the constructor, not an interface"} ] }, { "id": 2, "name": "interface-defined-at-consumer", "description": "Tests that interfaces are defined where consumed, not where implemented", "prompt": "I'm building a Go service that uses a UserStore. Should I define the UserStore interface in the same package as the PostgreSQL implementation or somewhere else? Show me the correct pattern.", "trap": "Without the skill, the model often defines the interface in the implementation package (next to the struct). The skill requires interfaces to be defined at the consumption site.", "assertions": [ {"id": "2.1", "text": "Defines the interface in the consuming package (e.g. service package), not the implementation package"}, {"id": "2.2", "text": "Explains the principle: accept interfaces, return structs"}, {"id": "2.3", "text": "The implementation package returns a concrete struct pointer"}, {"id": "2.4", "text": "The consumer depends on its own locally-defined interface"}, {"id": "2.5", "text": "Does NOT have the implementation package import the consumer's interface"} ] }, { "id": 3, "name": "container-not-passed-as-dependency", "description": "Tests that the DI container is never passed as a dependency (service locator anti-pattern)", "prompt": "I'm using samber/do for DI in my Go project. My UserService needs a Database and a Mailer. Should I pass the do.Injector to UserService so it can look up what it needs?", "trap": "Without the skill, the model may accept passing the injector/container as a dependency. The skill explicitly forbids this as the service locator anti-pattern.", "assertions": [ {"id": "3.1", "text": "Advises against passing the injector/container as a dependency"}, {"id": "3.2", "text": "Identifies this as the service locator anti-pattern"}, {"id": "3.3", "text": "Shows that the Injector should only exist at the composition root (main or app startup)"}, {"id": "3.4", "text": "Shows UserService receiving Database and Mailer directly as constructor parameters"}, {"id": "3.5", "text": "Shows the provider function using do.MustInvoke inside the provider, not inside UserService methods"} ] }, { "id": 4, "name": "manual-di-for-small-projects", "description": "Tests that small projects use manual DI, not a library", "prompt": "I'm building a small Go REST API with about 5 services: config, database, user repository, user service, and HTTP handler. What DI approach should I use?", "trap": "Without the skill, the model may recommend a DI library like Wire or Fx for any project. The skill says small projects (< 10 services) should use manual constructor injection.", "assertions": [ {"id": "4.1", "text": "Recommends manual constructor injection for a project with only 5 services"}, {"id": "4.2", "text": "Does NOT recommend a DI library as the pr