Home Backend Development Golang What is go language dependency injection?

What is go language dependency injection?

Jan 18, 2023 pm 04:41 PM
golang go language dependency injection

In the Go language, dependency injection (DI) is a design pattern that decouples dependencies between components; when needed, different components can obtain information from other components through a unified interface. objects and states. The benefit of dependency injection is decoupling; and decoupling can bring more benefits: enhanced code scalability, enhanced code maintainability, easier unit testing, etc.

What is go language dependency injection?

The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.

What is dependency injection?

When I first heard this word, I was confused and it was hard to pronounce. Maybe many students who have studied spring think this is very basic and easy to understand knowledge, but Because I have never learned Java or spring before, I was very confused when I first came into contact with this term.

Dependency injection, the English name is dependency injection, or DI for short. The word dependency is easy to understand. In software design, there are large and small dependencies from architectural modules to function methods.

For example, new B needs to be created before new A. A depends on B. At this time, we can say that B is a dependency of A. A controls B. There is a coupling relationship between AB, and the code design The idea is that it is best to achieve loose coupling. If B needs to be transformed one day, then A will also need to be transformed. You may be fine with this being a dependency, but if there is a series of dependencies between A->B->C->D->E->F, then it will be very troublesome to transform.

At this time, something is needed to decouple the strong coupling between them. How to decouple it? We can only use third-party forces. We put A to B This idea of ​​handing over control to a third party is called Inversion of Control (IOC Inversion Of Control), and this third party is called an IOC container. What the IOC container has to do is to create a new B, and then inject this instance of B into A. Then A can normally use the method based on B. This process is called dependency injection, and based on IOC This method is called dependency injection.

Simply put, dependency injection (DI) is a design pattern that decouples dependencies between components. When needed, different components can obtain objects and states in other components through a unified interface. The interface design of Go language avoids many situations where third-party dependency injection frameworks need to be used (such as Java, etc.). Our injection solution only provides very few injection solutions similar to those in Dager or Guice, and focuses on avoiding manual configuration of dependencies between objects and components.

The benefits of dependency injection

If you understand the idea of ​​dependency injection, you should also understand the biggest benefit it brings - decoupling .

And decoupling can bring more benefits: enhanced code scalability, enhanced code maintainability, easier unit testing, etc.

So how to implement dependency injection?

There are the following methods in Java:

  • Setter method injection: implement the public set method of specific properties to allow the external container to call the object of the dependent type .

  • Interface-based injection: Implement a specific interface for external containers to inject objects of dependent types.

  • Constructor-based injection: implement a constructor with specific parameters, and pass in the object of the dependent type when creating a new object.

  • Annotation-based injection: Add specific keywords to the code to achieve injection.

Annotations are the most common way. Like comments, they are not executed as code, but are specifically for others to read. But the readers of annotations are entirely humans, and the main readers of annotations, in addition to humans, are frameworks or precompilers.

Go dependency injection-wire

wire is an annotation-based dependency injection method. wire is a dependency injection tool open sourced by Google. We only need to tell wire the dependencies between types in a special go file, and it will automatically Help us generate code, help us create objects of specified types, and assemble its dependencies.

wire has two basic concepts, Provider (constructor) and Injector (injector).

Let wire know how to generate these dependent objects by providing the provider function. wire According to the injector function signature we defined, the complete injector function is generated. The injector function is the final function we need. It will Call provider in dependency order. The requirements of

wire are very simple. Create a new wire.go file (the file name can be arbitrary) and create our initialization function. For example, if we want to create and initialize a Mission object, we can do this:

//+build wireinject

package main

import "github.com/google/wire"

func InitMission(name string) Mission {
  wire.Build(NewMonster, NewPlayer, NewMission)
  return Mission{}
}
Copy after login

You can see the annotation on the first line: build wireinject, indicating that this is an injector. build is actually a feature of the Go language. Similar to C/C conditional compilation, some options can be passed in when executing go build, and based on these options it is decided whether certain files are compiled. The wire tool will only process files with wireinject, so our wire.go file must add this.

In the function, we call wire.Build() to pass in the constructor of the type that Mission depends on. For example, you need to call NewMission() to create the Mission type. NewMission() accepts two parameters, one of Monster type and one of Player type. Monster type objects need to be created by calling NewMonster(), and Player type objects need to be created by calling NewPlayer(). So NewMonster() and NewPlayer() we also need to pass to wire.

After writing the wire.go file and executing the wire command, a wire_gen.go file will be automatically generated.

// Code generated by Wire. DO NOT EDIT.

//go:generate wire
//+build !wireinject

package main

// Injectors from wire.go:

func InitMission(name string) Mission {
  player := NewPlayer(name)
  monster := NewMonster()
  mission := NewMission(player, monster)
  return mission
}
Copy after login

You can see that wire automatically generates the InitMission method for us. In this method, player, monster and mission are initialized in sequence. Then we only need to call this InitMission in our main function.

func main() {
  mission := InitMission("dj")

  mission.Start()
}
Copy after login

Before dependency injection was used, our code looked like this:

func main() {
  monster := NewMonster()
  player := NewPlayer("dj")
  mission := NewMission(player, monster)

  mission.Start()
}
Copy after login

Isn’t it much simpler? There are only three object initializations here. If there were more, you might not realize the benefits of dependency injection.

For example:

wire.go文件:
// +build wireinject
// The build tag makes sure the stub is not built in the final build.

package di

import (
	"github.com/google/wire"
)

//go:generate kratos t wire
func InitApp() (*App, func(), error) {
	panic(wire.Build(dao.Provider, service.Provider, http.New, grpc.New, NewApp))
}

实现文件:
//dao
var Provider = wire.NewSet(New, NewDB, NewRedis)
//service
var Provider = wire.NewSet(New, wire.Bind(new(pb.Server), new(*Service)))


生成的wire_gen.go 文件:
func InitApp() (*App, func(), error) {
	redis, cleanup, err := dao.NewRedis()
	if err != nil {
		return nil, nil, err
	}
	db, cleanup2, err := dao.NewDB()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	daoDao, cleanup3, err := dao.New(redis, db)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceService, cleanup4, err := service.New(daoDao)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	engine, err := http.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	server, err := grpc.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	app, cleanup5, err := NewApp(serviceService, engine, server)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return app, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}
Copy after login

So, what exactly is dependency injection?

It’s just encapsulation and decoupling.

【Related recommendations: Go video tutorial, Programming teaching

The above is the detailed content of What is go language dependency injection?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What libraries are used for floating point number operations in Go? What libraries are used for floating point number operations in Go? Apr 02, 2025 pm 02:06 PM

The library used for floating-point number operation in Go language introduces how to ensure the accuracy is...

What is the problem with Queue thread in Go's crawler Colly? What is the problem with Queue thread in Go's crawler Colly? Apr 02, 2025 pm 02:09 PM

Queue threading problem in Go crawler Colly explores the problem of using the Colly crawler library in Go language, developers often encounter problems with threads and request queues. �...

Explain the concept of Dependency Injection (DI) in PHP. Explain the concept of Dependency Injection (DI) in PHP. Apr 05, 2025 am 12:07 AM

The core value of using dependency injection (DI) in PHP lies in the implementation of a loosely coupled system architecture. DI reduces direct dependencies between classes by providing dependencies externally, improving code testability and flexibility. When using DI, you can inject dependencies through constructors, set-point methods, or interfaces, and manage object lifecycles and dependencies in combination with IoC containers.

In Go, why does printing strings with Println and string() functions have different effects? In Go, why does printing strings with Println and string() functions have different effects? Apr 02, 2025 pm 02:03 PM

The difference between string printing in Go language: The difference in the effect of using Println and string() functions is in Go...

How to solve the user_id type conversion problem when using Redis Stream to implement message queues in Go language? How to solve the user_id type conversion problem when using Redis Stream to implement message queues in Go language? Apr 02, 2025 pm 04:54 PM

The problem of using RedisStream to implement message queues in Go language is using Go language and Redis...

What should I do if the custom structure labels in GoLand are not displayed? What should I do if the custom structure labels in GoLand are not displayed? Apr 02, 2025 pm 05:09 PM

What should I do if the custom structure labels in GoLand are not displayed? When using GoLand for Go language development, many developers will encounter custom structure tags...

Golang's Purpose: Building Efficient and Scalable Systems Golang's Purpose: Building Efficient and Scalable Systems Apr 09, 2025 pm 05:17 PM

Go language performs well in building efficient and scalable systems. Its advantages include: 1. High performance: compiled into machine code, fast running speed; 2. Concurrent programming: simplify multitasking through goroutines and channels; 3. Simplicity: concise syntax, reducing learning and maintenance costs; 4. Cross-platform: supports cross-platform compilation, easy deployment.

Which libraries in Go are developed by large companies or provided by well-known open source projects? Which libraries in Go are developed by large companies or provided by well-known open source projects? Apr 02, 2025 pm 04:12 PM

Which libraries in Go are developed by large companies or well-known open source projects? When programming in Go, developers often encounter some common needs, ...

See all articles