又一个依赖注入的实现(Go)

2020-06-07 23:58:42 +08:00
 roy2220

go 依赖注入实现的不少,主要的有:

wire 的实现是代码生成的方式,每次修改都要重新 go generate,不太方便,还是运行时反射方便一些。

uber 的 dig 和 facebook 的 inject 是基于运行时反射的实现,使用方式上有些区别,但这两个用起来都不太直观。

我心中“理想”的样子:

Foo {
  A int `export:"x"` // 声明导出 x
}
func (Foo) SetUp() { Foo.A = 1 } // 这里手动设置 A,在 SetUp 返回后自动导出 x=Foo.A


Bar {
  B int `export:"y"` // 声明导出 b
}
func (Bar) SetUp() { Bar.B = 2 } // 这里手动设置 B,在 SetUp 返回后自动导出 y=Bar.B


Baz {
  A int `import:"x"` // 声明导入 x
  B int `import:"y"` // 声明导入 y
  C int `export:"z"` // 声明导出 z
}
func (Baz) SetUp() { Baz.C = Baz.A + Baz.B } // SetUp 被调用时,保证 x 、y 的值已被自动导入,即 Baz.A=x Baz.B=y 。接着是手动计算 C 的值( z=x+y ),SetUp 返回后自动导出 z=Baz.C 。


Qux {
  C int `import:"z"` // 声明导入 z
}
func (Qux) SetUp() { println(Qux.C) } // 同理 SetUp 被调用时,z 的值已被自动导入到 C,打印输出 Qux.C 的值为 3 。
  1. 库要做的事情就是分析 import 、export 的依赖关系,有没有循环引用之类的,并在恰当的时机拷贝 export 的值到 import 、在恰当的时机调用结构体的 SetUp 方法等。

  2. 应当提供一种拦截机制:值被 export 后,到真正传递到 import 的期间,可以安插一些 filter,对值进行操作或修改,并且这些 filter 可以设置优先级。这样方便实现各种灵活的定制。

目前上述的点都已经实现,代码提交在:

https://github.com/roy2220/depinj

思绪有点混乱,看不懂我在写啥没关系😂,github 上有 example,有兴趣跑一跑就明白了。。。欢迎讨论交流

2081 次点击
所在节点    分享创造
1 条回复
my3157
2020-06-08 19:41:52 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/679530

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX