Dependency Injection With Golang Wire
Dependency Injection is the idea that your components (usually structs in go or interfaces based on reflection)
should receive their dependencies when being created.
Google introduce wire
as dependency injection, and used by google-cloud-platform library.
In here, i will explain a simple case, how to use wire
as dependency injection.
//repository.go
package repository
type (
Repository interface {
Query() string
}
Repo struct{}
)
func NewRepository() *Repo {
return &Repo{}
}
func (r *Repo) Query() string {
return "SELECT * FROM queries"
}
//service.go
package service
import (
"github.com/faizalpribadi/practice/app/repository"
)
type (
Service interface{}
Svc struct {
repo repository.Repository
}
)
func NewService(repo repository.Repository) *Svc {
return &Svc{repo: repo}
}
func (s *Svc) GetQuery() string {
return s.repo.Query()
}
//container.go
//+build wireinject
package container
import (
"github.com/faizalpribadi/practice/app/repository"
"github.com/faizalpribadi/practice/app/service"
"github.com/google/wire"
)
var repositorySet = wire.NewSet(repository.NewRepository, wire.Bind(new(repository.Repository), new(*repository.Repo)))
func NewContainer() *service.Svc {
wire.Build(repositorySet, service.NewService)
return &service.Svc{}
}
after all the code has been created, we will generate wire_gen.go
by command from wire
:
// Code generated by Wire. DO NOT EDIT.
//go:generate wire
//+build !wireinject
package container
import (
"github.com/faizalpribadi/practice/app/repository"
"github.com/faizalpribadi/practice/app/service"
"github.com/google/wire"
)
// Injectors from container.go:
func NewContainer() *service.Svc {
repo := repository.NewRepository()
svc := service.NewService(repo)
return svc
}
// container.go:
var repositorySet = wire.NewSet(repository.NewRepository, wire.Bind(new(repository.Repository), new(*repository.Repo)))
and the final part is run the code is working as expected.
package main
import (
"fmt"
"github.com/faizalpribadi/practice/container"
)
func main() {
c := container.NewContainer()
fmt.Println(c.GetQuery())
}