这里的 client 举个例子,redis/mq/db 的 client 等,应该放在哪个目录下? pkg 下统一初始化好全局变量?还是 service 目录下跟着 service 走?
1
BeautifulSoap 176 天前 via Android 1
lz 指 DDD 还是普通开发
普通开发随便你折腾,一般找个地方 singleton 一下就行了,尤其 db ,每个实例内部维护有链接池,每次都新 new 的话 db 连接会很快耗尽(都是生产事故的教训) DDD 的话 domain service 里肯定不能 new 这种 infra 的,项目启动时 new 一下塞 di 里,或者用全局变量做个 lazyload 的 singleton 。我更喜欢在 domain 里为简单的 client 各自定义出一个抽象的接口,然后 domain entity 数据通过 repository 接口和 infra 进行交互 |
2
ninjashixuan 176 天前 1
项目不大就是全局变量然后塞 context 里传递,不然就折腾 wire ,dig 等 DI 工具。
|
3
lasuar 175 天前 1
要么统一放到 global/ 下面,要么依赖注入。
|
4
wwhontheway OP @BeautifulSoap 普通开发,也不想依赖注入
|
5
bv 175 天前
依赖注入,用框架也可以,自己依赖注入也可以:
```go func Run(cfg Config) error { db, err := mysql.Open(cfg.Database) if err != nil { return err } defer db.Close() mq, err := kafka.Open(cfg.Kafka) if err != nil { return err } defer mq.Close() rdb, err := redis.Open(cfg.Redis) if err != nil { return err } defer rdb.Close() bar := NewBar(db, mq, rdb) return bar.Foo() } func NewBar(db *sql.DB, mq *kafka.Client, rdb *redis.Client) *Bar { return &Bar{ db: db, mq: mq, rdb: rdb, } } type Bar struct { db *sql.DB mq *kafka.Client rdb *redis.Client } func (b *Bar) Foo() error { _, err := b.db.Exec("SELECT 1") return err } ``` |
6
devhxy 175 天前
只要涉及到 singleton ,di 是最稳妥的办法,选个轻量级的就好
推荐:github.com/samber/do |
7
dobelee 175 天前
微服务的话跟着 service 走就行。全局变量不是好范式,也不好 mock 。除非你要做成一个包单独提供服务。
|
8
RedisMasterNode 175 天前
不是直接在项目根目录下做个 /datasource (命名可改)然后放各种 client 的目录就好了吗...
./ --- cmd/ --- pkg/ --- internal/ --- ... --- datasource --------- mysql --------- redis --------- kafka 然后 internal 里调用 GetMySQL(xxx) 或者 GetRedis(xxx) 就能直接用了 为啥要塞到某个结构体里... |
9
sophos 175 天前
|
10
Desdemor 174 天前
DDD 的话跟 1 楼差不多, 项目启动的时候 依赖注入,给你个参考: https://github.com/8treenet/freedom
|
11
qloog 159 天前
放在各自的目录下去,比如:
db 在 internal/models 下 redis 在 internal/cache 下 然后统一在 main.go 里调用对应的方法进行初始化 参看: https://github.com/go-eagle/eagle/blob/master/main.go mq 是直接放到公共的 pkg 里的目录 比如 queue, 最后也在在启动服务的 main.go 里进行启动 参看: https://github.com/go-eagle/eagle/blob/master/examples/queue/rabbitmq/consumer/main.go |