过去几年里我一直使用 Java。最近,用 Go 建立了一个小项目,然而 Go 生态系统中依赖注入(DI)功能缺乏让我震惊。于是我决定尝试使用 Uber 的 库来构建我的项目,期间感触颇深。
initdigDI 的简要概述
依赖注入是指你的组件(通常在 Go 中是 struct )在创建时,就应该获取它们依赖关系的一种思想。这与那些组件在初始化过程中,就建立自身依赖关系的反关联模式不同 。我们来看一个例子。
ServerConfigServerConfigServerConfigConfigbuildMyConfigSomehowConfignewConfig这是 DI 方式:
ServerConfigConfigNewConfigNewConfigServerserverconfigserverConfig,Config这是 DI 框架可以提供帮助的地方。 DI 框架通常提供两个功能:
- “提供”新组件。简而言之,这告诉 DI 框架一旦你有这些组件,还需要其他什么组件(依赖关系)以及如何去构建。
- “检索”构建组件。
DI 框架通常基于您告诉它的 “providers” 构建依赖图并确定如何构建对象。这在没有具体例子的情况下很难理解,所以让我们来看一个中等大小的例子。
示例程序
GET/peoplemainPersonPersonIdNameAgeConfigPersonPersonEnabledDatabasePathPortConfig*sql.DBPersonRepositoryPersonPersonRepositoryFindAllPersonPersonRepositoryPersonServicePersonServiceConfigPersonRepositoryFindAllPersonRepositoryServerPersonServiceServerPersonServiceConfig好的,我们了解了系统的所有组件。现在我们该如何在实际中初始化它们并启动我们的系统?
传统的 main()
main()ConfigConfigPersonRepositoryPersonServiceServermainmain您可能已经猜到,依赖注入框架可以帮助我们解决这个问题。一起来看看。
创建容器
digProvideInvoke首先,我们构建一个新容器。
ProvideConfigConfig*sql.DBConfigNewConfigConnectDatabaseInvoke容器做了一些非常聪明的东西,如下:
*sql.DBConnectDatabaseConnectDatabaseConfigConfigNewConfigNewConfigNewConfigConfigConnectDatabaseConnectionDatabase*sql.DBInvoke这是容器为我们做的很多工作。事实上,它做的更多。容器很智能,可以构建每种类型有且仅有一个实例。这意味着如果我们在多个地方(比如多个存储库)使用它,我们永远不会意外地创建第二个数据库连接。
较好的 main() 写法
digInvokeerrorInvokeInvoke虽然这个例子很小,但应该很容易看出这种方法的一些好处超过了“常规“的 main 。随着应用程序变得越来越大,这些好处变得更加明显。
PersonRepositoryConfigNewPersonRepositoryConfiginitinit一个值得传播的想法
dig本文由 原创编译, 荣誉推出