Mastering Dependency Injection in Go with Google Wire

This article introduces Google Wire, a static‑analysis‑based dependency injection tool for Go, covering its key features, installation steps, core usage patterns—including defining dependencies, creating providers, generating code, and best practices such as modular management, interface abstraction, and testing with mock implementations.

Ops Development & AI Practice
Ops Development & AI Practice
Ops Development & AI Practice
Mastering Dependency Injection in Go with Google Wire

Dependency Injection (DI) is a design pattern that moves dependency creation outside of a class to improve testability, maintainability, and flexibility. In Go, github.com/google/wire is a powerful, efficient DI tool that uses static code analysis to generate initialization code.

1. Introduction to Google Wire

Google Wire is an open‑source DI generator for Go. It reads annotations and performs static analysis to automatically generate dependency‑initialization code, simplifying manual dependency management.

Key Features

Static analysis : generates code at compile time, avoiding runtime overhead.

Simplified dependency management : automatically creates initialization code, reducing errors and complexity.

Easy integration : works with existing Go projects without major code changes.

2. Installing Google Wire

Install Wire using Go's package tool: go get -u github.com/google/wire/cmd/wire Verify the installation: wire help If the help output appears, the installation succeeded.

3. Basic Usage

1. Define dependencies

Example with a simple application that needs a database connection and an HTTP server:

package main

import (
    "fmt"
    "net/http"
)

// Database defines a DB struct
type Database struct {
    DSN string
}

// NewDatabase creates a new Database instance
func NewDatabase(dsn string) *Database {
    return &Database{DSN: dsn}
}

// Server defines an HTTP server struct
type Server struct {
    DB *Database
}

// NewServer creates a new Server instance
func NewServer(db *Database) *Server {
    return &Server{DB: db}
}

2. Create Provider

Providers describe how to construct dependencies. In wire.go:

// +build wireinject

package main

import "github.com/google/wire"

// InitializeServer declares that Server depends on Database and uses NewDatabase and NewServer to build them.
func InitializeServer(dsn string) *Server {
    wire.Build(NewDatabase, NewServer)
    return &Server{}
}

3. Generate code

Run the Wire command to generate the concrete initialization code: wire The generated wire_gen.go looks like:

// Code generated by Wire. DO NOT EDIT.

package main

import "github.com/google/wire"

func InitializeServer(dsn string) *Server {
    database := NewDatabase(dsn)
    server := NewServer(database)
    return server
}

4. Use generated code

In main.go:

package main

import "fmt"

func main() {
    dsn := "user:password@/dbname"
    server := InitializeServer(dsn)
    fmt.Println("Server initialized with database:", server.DB.DSN)
}

4. Best Practices

1. Modular dependency management

Separate dependencies per module, e.g., a dedicated file for database providers:

// database.go
package main

import "github.com/google/wire"

var DatabaseSet = wire.NewSet(NewDatabase)

2. Use interfaces

Define dependencies as interfaces to increase flexibility:

// database.go
package main

type Database interface {
    Connect() error
}

type MySQLDatabase struct {
    DSN string
}

func (db *MySQLDatabase) Connect() error { return nil }

func NewMySQLDatabase(dsn string) *MySQLDatabase {
    return &MySQLDatabase{DSN: dsn}
}

// wire.go
package main

import "github.com/google/wire"

var DatabaseSet = wire.NewSet(NewMySQLDatabase, wire.Bind(new(Database), new(*MySQLDatabase)))

3. Testing

Dependency injection makes unit testing straightforward by injecting mock implementations:

// server_test.go
package main

import (
    "testing"
    "github.com/stretchr/testify/assert"
)

type MockDatabase struct{}

func (db *MockDatabase) Connect() error { return nil }

func TestServer(t *testing.T) {
    db := &MockDatabase{}
    server := NewServer(db)
    assert.NotNil(t, server)
}

5. Conclusion

Google Wire provides fast, static‑analysis‑based code generation for dependency injection, reducing manual wiring, improving modularity, and simplifying testing in Go projects.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Code GenerationGodependency-injectionstatic analysisProviderGoogle Wire
Ops Development & AI Practice
Written by

Ops Development & AI Practice

DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.