抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

什么是控制反转(IOC)?

Inversion of Control (IoC) 是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)

用大白话说就是你想实例化一个对象,但是这个对象又层层依赖其他对象,原本你需要由自己一个个去处理好这些对象间的依赖关系,现在可以解放双手交给IOC框架自己去处理了,不需要自己每次都去写实例化部分的代码了

无IOC的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main

import (
"fmt"

"gorm.io/driver/mysql"
"gorm.io/gorm"
)

type MysqlConfig struct {
Dsn string
MaxIdle int
MaxOpen int
MaxLife int
}

type DataSourceType struct {
DB *gorm.DB
}

var DataSource *DataSourceType

func main() {

// no ioc
mysqlConfig := &MysqlConfig{
Dsn: "dsn",
}
gormDb, err := gorm.Open(mysql.New(mysql.Config{
DSN: mysqlConfig.Dsn,
}), &gorm.Config{SkipDefaultTransaction: true})
if err != nil {
fmt.Errorf("Db init error : %s", err.Error())
}
DataSource = &DataSourceType{
DB: gormDb,
}
var userCount int64
if err := DataSource.DB.Table("user").Count(&userCount).Error; err != nil {
fmt.Println("User count error")
}
fmt.Printf("no ioc User count: %v", userCount)
}

运行结果

1
2
$ go run ioc.go
no ioc User count: 12

Uber-go/Dig

Uber-go/dig 是一个基于反射的 Go 依赖注入工具包。

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package main

import (
"fmt"

"go.uber.org/dig"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)

type MysqlConfig struct {
Dsn string
MaxIdle int
MaxOpen int
MaxLife int
}

type DataSourceType struct {
DB *gorm.DB
}

var DataSource *DataSourceType

func main() {
mysqlConfig := &MysqlConfig{
Dsn: "dsn",
}

// uber-go/dig Constructors for different types are added to the container by using the Provide method.
c := dig.New()
if err := c.Provide(func() *MysqlConfig {
return mysqlConfig
}); err != nil {
fmt.Printf("Provide error : %s", err)
}
if err := c.Provide(func(mconfig *MysqlConfig) (*gorm.DB, error) {
return gorm.Open(mysql.New(mysql.Config{
DSN: mconfig.Dsn,
}), &gorm.Config{SkipDefaultTransaction: true})
}); err != nil {
fmt.Printf("Provide error : %s", err)
}

// using *gorm.DB from container
if err := c.Invoke(func(db *gorm.DB) {
DataSource = &DataSourceType{
DB: db,
}
}); err != nil {
fmt.Printf("Provide error : %s", err)
}

var userCount int64
if err := DataSource.DB.Table("user").Count(&userCount).Error; err != nil {
fmt.Println("User count error")
}
fmt.Printf("uber-go/dig User count: %v", userCount)

}

运行结果

1
2
$ go run ioc.go
uber-go/dig User count: 12

以下内容正在施工中

google/wire

facebook-go/inject

参考资料

评论