常见问题解答
Wire和其他Go依赖注入工具有什么不同?
其他Go依赖注入工具如dig或facebookgo/inject是基于反射实现。Wire作为代码生成器运行,这意味着注入器不需要对运行时库进行调用。这使得更容易进行工具化初始化检查和正确的交叉引用,比如guru。
Wire和其他非Go依赖注入工具(如Dagger 2)有什么关系?
Wire的方法是受到Dagger 2的启发。然而,Wire的目的并不是为了模拟其他语言的依赖注入工具:设计空间和要求是相当不同的。例如,Go编译器不支持类似于Java的注解处理机制。语言和语言习惯的差异必然需要以不同的基本元素和API来实现。
为什么要使用伪函数创建供应程序集或注入器?
在早期的Wire原型中,Wire指令是特殊格式的注释。这一开始看起来很有吸引力,因为这意味着没有编译时或运行时影响。然而,这种非结构化的方法对于没有专门修改以了解Wire评论格式的其他工具来说变得不透明。像gorename
或guru这样的工具将无法识别对注释中现有标识符的引用,除非它们被特别修改以理解Wire的评论格式。通过将引用移动到空操作函数调用中,Wire可以与其他Go工具无缝地 interoperates。
如果我的依赖关系图具有两个相同类型的依赖关系怎么办?
这最常见于一些常见类型,如string
。这个问题的一个例子是:
type Foo struct { /* ... */ }
type Bar struct { /* ... */ }
func newFoo1() *Foo { /* ... */ }
func newFoo2() *Foo { /* ... */ }
func newBar(foo1 *Foo, foo2 *Foo) *Bar { /* ... */ }
func inject() *Bar {
// ERROR! Multiple providers for *Foo.
wire.Build(newFoo1, newFoo2, newBar)
return nil
}
Wire不允许在提供给wire.Build
的提供程序的传递封闭的多个提供程序存在相同类型的多个提供程序,因为这通常是一个错误。对于需要多个相同类型的依赖关系的合法情况,需要为其命名一个新类型。例如,你可以将OAuth凭据命名为它们连接的服务。一旦你有了一个合适的不同类型,你就可以在Wire中将类型进行包装和取消包装。继续我们上面的例子:
type OtherFoo Foo
func newOtherFoo() *OtherFoo {
// Call the original provider...
foo := newFoo2()
// ...then convert it to the new type.
return (*OtherFoo)(foo)
}
func provideBar(foo1 *Foo, otherFoo *OtherFoo) *Bar {
// Convert the new type into the unwrapped type...
foo2 := (*Foo)(otherFoo)
// ...then use it to call the original provider.
return newBar(foo1, foo2)
}
func inject() *Bar {
wire.Build(newFoo1, newOtherFoo, provideBar)
return nil
}
为什么Wire禁止多次包含相同提供程序?
Wire禁止这样做是为了与指定同一类型的多个提供程序是错误的原则保持一致。在表面上,Wire可以允许重复,但这会引入一些意外的后果:
- Wire必须指定哪些重复是允许的:两个
wire.Value
调用是否会被视为“相同”的? - 如果一个提供程序集更改了它用于提供类型的函数,那么这可能会破坏一个应用程序,因为它可能会在另一个指定“相同”的提供程序集之间引入新的冲突。
因此,我们决定这种情况是一个错误的,知道我们随时可以放宽这个限制。用户可以创建一个新的不具有冲突类型的提供程序集。proposed subtract command将自动执行这个过程。
为什么Wire要求明确声明类型提供接口类型?
绑定是显式的原因是为了避免将新类型添加到提供程序图中并实现相同接口时导致图形中断,因为这可能是令人惊讶的。虽然这确实会导致更多的输入,但最终效果是开发人员的意图在代码中更加明确,这与Go哲学最一致。
有一个未决问题来考虑改善这个问题。
我应该在小型应用程序中使用Wire吗?
可能不需要。Wire旨在自动化在更大的应用程序中找到的更复杂的设置代码。对于小型应用程序,手动链接依赖关系更简单。
谁在使用Wire?
Wire还很新,用户基数还不太大。但是,我们听到很多希望简化其应用程序的Go用户的兴趣。如果您的项目或公司正在使用Wire,请通过电子邮件或提交拉取请求让我们知道,以更正本节。