给定以下代码:
package main
import (
"fmt"
)
type datstr string
type Guy interface {
SomeDumbGuy() string
}
func (d *datstr) SomeDumbGuy() string {
return "some guy"
}
func someConsumer(g Guy) {
fmt.Println("Hello, " + g.SomeDumbGuy())
}
func main() {
var d datstr
someConsumer(&d)
}
在main中完成的将组件连接在一起是将依赖关系连接在一起的正确方式吗?看起来我在代码中已经不再使用这种方式了。是否有比这更好的通用模式,或者是我想多了?
9条答案
按热度按时间e0uiprwp1#
最好的做法是不要使用DI库。Go语言应该是一种简单易用的语言。DI库/框架会将其抽象化(在某种程度上使DI变得神奇)。
whlutmcx2#
谷歌的Wire看起来很有前途,有一些关于它的文章:
3wabscal3#
是的,facebookgo的注入库允许你把你的注入成员,并会为你连接起来的图形。
编码:https://github.com/facebookgo/inject
文件:https://godoc.org/github.com/facebookgo/inject
以下是文档中的代码示例:
czfnxgou4#
你也可以试试Dargo,这是一款新的软件,但是它有一些facebook one没有的特性,代码是here。
下面是一个例子:
在本例中,一个名为SimpleService的服务将注入一个日志记录器。日志记录器本身是一个dargo服务,绑定了一个创建方法。该创建方法如下所示:
SimpleService的绑定将提供用于实现接口的结构体。该结构体有一个用inject注解的字段,后跟要注入的服务的名称。这是接口和用于实现它的结构体:
logger服务和SimpleService都绑定到ServiceLocator中,这通常在程序开始时完成:
返回的定位器可用于查找SimpleService服务。SimpleService绑定到Singleton作用域(默认作用域)中,这意味着仅在第一次查找或注入它时才创建它,并且不会再次创建。另一方面,LoggerService位于PerLookup作用域中,这意味着每次注入或查找它时都将创建一个新的。
以下是使用查找服务的代码:
支持任意深度的注入(ServiceA可以依赖ServiceB,ServiceB依赖ServiceC,依此类推)。服务还可以依赖任意数量的服务(ServiceA可以依赖服务D、E和F等)。但是,服务不能有循环依赖关系。
qnakjoqk5#
Uber的Dig非常棒,下面是一篇关于它的博客文章:Dependency Injection in Go
r8uurelv6#
如果你仍然对找到一个使用最少反射的Go语言DI库感兴趣,我做了一个叫axon的,它基于Google的Guice,所以如果你来自Java世界(像我一样),它应该很适合你期望它如何工作。
我在Web服务器中使用过它,它没有任何问题,速度足够快,对在CLI中使用没有任何影响。
amrnrhlw7#
你也可以查看Uber的fx来寻找一个更通用的应用框架,它使用了Uber的底层技术,@yndolok已经提到过。
fx github链接:https://github.com/uber-go/fx
gijlo24d8#
作为作者,我可能有偏见,但https://github.com/muir/nject是Go语言最好的DI框架,它易于使用,并提供了非常完整的功能集。
它是基于类型的,给定一个函数列表,这些函数消耗和产生各种类型,它会把它们连接在一起,这样列表中的最后一个函数就会被调用,而其他任何需要为最后一个函数提供参数的函数也会被调用.
e0bqpujr9#
Go1.18增加了对泛型的支持,我认为依赖注入可以通过使用这种语言特性来实现,它现在已经内置在语言中,而不是外部依赖https://go.dev/blog/intro-generics