Dependency Injection With Golang Wire
Aug 10, 2019
2 minute read

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())
}