golang-google-wire

安装量: 786
排名: #5030

安装

npx skills add https://github.com/samber/cc-skills-golang --skill golang-google-wire

Persona: You are a Go architect using wire for compile-time DI. You let the compiler catch missing dependencies, treat wire_gen.go as committed source, and re-run wire ./... after every graph change. Using google/wire for Compile-Time Dependency Injection in Go Code-generation DI toolkit. Wire resolves the dependency graph at compile time and emits plain Go constructor calls — no runtime container, no reflection. Errors appear when you run wire ./... , not at first request. Note: google/wire was archived in August 2025 (feature-complete; bug fixes still accepted). Official Resources: pkg.go.dev · github.com/google/wire · User Guide · Best Practices This skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform. go install github.com/google/wire/cmd/wire@latest go get github.com/google/wire wire vs. Runtime DI Concern wire dig / fx / samber/do Resolution Compile time (codegen) Runtime (reflection) Error detection wire ./... fails First Invoke /startup Runtime container None — plain Go calls Present Lifecycle hooks Not built in fx: OnStart/OnStop Generated files wire_gen.go (committed) None For lifecycle, lazy loading, and a full matrix see samber/cc-skills-golang@golang-dependency-injection . Providers A provider is any Go function — inputs are dependencies, outputs are provided types. Three return forms: func NewConfig ( ) * Config { return & Config { Addr : ":8080" } } func NewDB ( cfg * Config ) ( * sql . DB , error ) { return sql . Open ( "postgres" , cfg . DSN ) } func NewRedis ( cfg * Config ) ( * redis . Client , func ( ) , error ) { // cleanup chained in reverse order c := redis . NewClient ( & redis . Options { Addr : cfg . RedisAddr } ) return c , func ( ) { c . Close ( ) } , nil } Provider Sets wire.NewSet groups providers for reuse. Sets can reference other sets. // infra/wire.go var InfraSet = wire . NewSet ( NewConfig , NewDB , NewRedis , ) // service/wire.go var ServiceSet = wire . NewSet ( NewUserRepo , NewUserService , wire . Bind ( new ( UserStore ) , new ( * UserRepo ) ) , // interface binding ) Keep sets small: library sets expose a stable surface (adding inputs or removing outputs breaks downstream injectors). One set per package is a useful default. Injectors and //go:build wireinject The injector file declares the initialization function. Wire generates its body into wire_gen.go and replaces the stub. //go:build wireinject package main import "github.com/google/wire" // Wire generates the body of this function. func InitApp ( ) ( * App , func ( ) , error ) { wire . Build ( InfraSet , ServiceSet , NewApp ) return nil , nil , nil // replaced by codegen } The //go:build wireinject tag prevents the stub from being compiled into the binary — only wire_gen.go (which has no such tag) makes it through go build . Without this tag, both files define the same function, causing a compile error. Alternative syntax when a dummy return is inconvenient: func InitApp ( ) ( * App , func ( ) , error ) { panic ( wire . Build ( InfraSet , ServiceSet , NewApp ) ) } Interface Bindings Wire forbids implicit interface satisfaction — you must declare bindings explicitly so the graph is unambiguous when multiple types implement the same interface. var Set = wire . NewSet ( NewPostgresUserRepo , wire . Bind ( new ( UserStore ) , new ( * PostgresUserRepo ) ) , // tell wire: PostgresUserRepo satisfies UserStore ) Explicit bindings prevent graph breakage when a new type implementing the same interface is added elsewhere. Struct Providers and Values wire.Struct fills struct fields from the graph without a manual constructor. Tag fields wire:"-" to exclude them. wire . Struct ( new ( Server ) , "Logger" , "DB" ) // inject named fields wire . Struct ( new ( Server ) , "" ) // inject all non-excluded fields wire . Value ( Foo { X : 42 } ) // constant expression (no fn calls / channels) wire . InterfaceValue ( new ( io . Reader ) , os . Stdin ) // interface-typed literal wire . FieldsOf ( new ( Config ) , "DSN" , "Addr" ) // promote struct fields as graph nodes See advanced.md for the wire:"-" exclusion tag and wire.FieldsOf details. Disambiguating Duplicate Types Wire forbids two providers for the same type. Wrap the underlying type in distinct named types so each has exactly one provider: type PrimaryDSN string type ReplicaDSN string Full Application Example // wire.go — injector, excluded from binary via build tag //go:build wireinject package main func InitApp ( ) ( * App , func ( ) , error ) { wire . Build ( config . ConfigSet , infra . InfraSet , service . ServiceSet , NewApp ) return nil , nil , nil } // main.go func main ( ) { app , cleanup , err := InitApp ( ) if err != nil { log . Fatal ( err ) } defer cleanup ( ) app . Run ( ) } Wire generates wire_gen.go (plain Go, committed, DO NOT EDIT). For a full example with per-package sets, cleanup-heavy graphs, and generated output, see recipes.md . Codegen Workflow wire ./ .. .

regenerate all injectors in the module

wire check ./ .. .

validate graph without regenerating (fast CI check)

Run wire ./... after every constructor signature change. Add //go:generate go run github.com/google/wire/cmd/wire to injector files so go generate ./... also works. Commit wire_gen.go — it must stay in sync for CI builds. Best Practices Never edit wire_gen.go — it is overwritten on every wire ./... run. Treat it as a build artifact that happens to be committed; source of truth is the provider and injector files. Always add //go:build wireinject to injector files — omitting it causes duplicate-symbol compile errors because both the stub and the generated file define the same function. Use named types to distinguish values of the same underlying type — wire enforces one provider per type; named types like type DSN string let you have PrimaryDSN and ReplicaDSN coexist. Keep library provider sets minimal and backward-compatible — adding new required inputs breaks downstream injectors; removing outputs does too. Introduce only newly-created types in the same release. Return (T, func(), error) from cleanup providers and let wire chain them — wire generates the correct reverse-order cleanup and handles partial failures (if construction fails midway, only already-built cleanups run). Keep injector files focused — one function per file, one package import at a time. Fat injectors with dozens of wire.Build arguments are hard to reason about; delegate to per-package sets. Common Mistakes Mistake Fix Editing wire_gen.go manually Never edit it. Change providers or injectors and re-run wire ./... . Missing //go:build wireinject Add the tag as the very first line of every injector file. Two providers returning sql.DB Wrap with named types ( type PrimaryDB sql.DB or a wrapper struct). Injecting an interface without wire.Bind Add wire.Bind(new(MyInterface), new(*MyImpl)) to the provider set. Forgetting to re-run wire ./... after changes Run wire before go build ; add it to go generate or a Makefile target. Calling cleanup() without guarding for nil Wire returns nil cleanup on construction error; guard with if cleanup != nil { defer cleanup() } . Testing Wire generates plain Go constructors, so unit tests use manual injection — no container to clone or reset. For testing patterns (test injectors swapping real providers for fakes, CI stale-check for wire_gen.go ), see testing.md . Further Reading advanced.md — cleanup chains, multiple injectors, set nesting, error catalogue, codegen flags, quick reference recipes.md — HTTP server, multi-injector build, cleanup-heavy graph, CLI embedding testing.md — test injectors, fake bindings, CI stale check Cross-References → See samber/cc-skills-golang@golang-dependency-injection skill for DI concepts and library comparison → See samber/cc-skills-golang@golang-uber-dig skill for runtime reflection-based DI without lifecycle → See samber/cc-skills-golang@golang-uber-fx skill for runtime DI with lifecycle hooks, modules, and signal-aware Run() → See samber/cc-skills-golang@golang-samber-do skill for generics-based DI without reflection → 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 If you encounter a bug or unexpected behavior in google/wire, open an issue at https://github.com/google/wire/issues .

返回排行榜