Compile-time dependency injection from Google.
// wire.go
//go:build wireinject
// +build wireinject
package main
import "github.com/google/wire"
func InitializeApp() (*App, error) {
wire.Build(
NewDatabase,
NewUserRepository,
NewUserService,
NewApp,
)
return nil, nil
}
# Generate wire_gen.go
wire ./...
// Providers are constructors
func NewDatabase(cfg *Config) (*sql.DB, error) {
return sql.Open("postgres", cfg.DatabaseURL)
}
func NewUserRepository(db *sql.DB) *UserRepository {
return &UserRepository{db: db}
}
func NewUserService(repo *UserRepository) *UserService {
return &UserService{repo: repo}
}
func NewApp(svc *UserService) *App {
return &App{userService: svc}
}
// Group related providers
var DatabaseSet = wire.NewSet(
NewDatabase,
NewUserRepository,
NewPostRepository,
)
var ServiceSet = wire.NewSet(
NewUserService,
NewPostService,
)
// Use sets in injector
func InitializeApp(cfg *Config) (*App, error) {
wire.Build(
DatabaseSet,
ServiceSet,
NewApp,
)
return nil, nil
}
type UserRepository interface {
FindByID(id int) (*User, error)
}
type userRepository struct {
db *sql.DB
}
func NewUserRepository(db *sql.DB) *userRepository {
return &userRepository{db: db}
}
// Bind implementation to interface
var RepositorySet = wire.NewSet(
NewUserRepository,
wire.Bind(new(UserRepository), new(*userRepository)),
)
type Config struct {
DatabaseURL string
Port int
}
// Provide struct fields
var ConfigSet = wire.NewSet(
wire.Struct(new(Config), "*"), // All fields
// or
wire.Struct(new(Config), "DatabaseURL", "Port"), // Specific fields
)
// Field providers must exist
func InitializeApp(dbURL string, port int) (*App, error) {
wire.Build(
ConfigSet,
// ...
)
return nil, nil
}
func InitializeApp() (*App, error) {
wire.Build(
wire.Value(&Config{
DatabaseURL: "postgres://...",
Port: 8080,
}),
NewDatabase,
NewApp,
)
return nil, nil
}
// Or interface value
wire.InterfaceValue(new(io.Writer), os.Stdout)
func NewDatabase(cfg *Config) (*sql.DB, func(), error) {
db, err := sql.Open("postgres", cfg.DatabaseURL)
if err != nil {
return nil, nil, err
}
cleanup := func() {
db.Close()
}
return db, cleanup, nil
}
// Injector returns cleanup
func InitializeApp(cfg *Config) (*App, func(), error) {
wire.Build(
NewDatabase,
NewApp,
)
return nil, nil, nil
}
// Usage
app, cleanup, err := InitializeApp(cfg)
if err != nil {
log.Fatal(err)
}
defer cleanup()
// wire.go
//go:build wireinject
package main
import "github.com/google/wire"
// For HTTP server
func InitializeHTTPServer(cfg *Config) (*HTTPServer, func(), error) {
wire.Build(
DatabaseSet,
HTTPSet,
)
return nil, nil, nil
}
// For CLI
func InitializeCLI(cfg *Config) (*CLI, error) {
wire.Build(
DatabaseSet,
CLISet,
)
return nil, nil
}
// Mock for testing
type mockUserRepository struct{}
func (m *mockUserRepository) FindByID(id int) (*User, error) {
return &User{ID: id, Name: "Test"}, nil
}
// Test injector
func InitializeTestApp() (*App, error) {
wire.Build(
wire.Value(&mockUserRepository{}),
wire.Bind(new(UserRepository), new(*mockUserRepository)),
NewUserService,
NewApp,
)
return nil, nil
}
wire.Bind for testabilitywireinject build tagwire ./... after changesnpx skills add ngxtm/Wire Dependency Injection下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer