为了账号安全,请及时绑定邮箱和手机立即绑定

使用 go 接口进行依赖注入

使用 go 接口进行依赖注入

Go
蛊毒传说 2023-01-03 14:10:57
在阅读了一些关于它的文档后,我试图通过 go 接口使用一些依赖注入。我有两种方法应该实现一个接口type Shooter interface {    Spec(ev v1alpha1.Ev) (v1beta1.Shoot, error)}type Project struct {    Name string}https://github.com/JennyMet/testint/blob/master/internal/infra/common.go#L8具体实现在这里 https://github.com/JennyMet/testint/blob/master/internal/infra/azure/azure.go#L13 https://github.com/JennyMet/testint/blob/master/internal/基础设施/gcp/gcp.go#L13例如func (n Project) Spec(ev v1alpha1.Ev) (v1beta1.Shoot, error) {    var shoot = v1beta1.Shoot{}    fmt.Println(shoot, ev)    return shoot, nil}现在我想在上面的包中获得具体的实现,我尝试了以下https://github.com/JennyMet/testint/blob/master/internal/infra/provider.go#L16func kind(ev v1alpha1.Ev, namespace string) (v1beta1.Shoot, error) {    var shoot v1beta1.Shoot    var e error    switch ev.Spec.Infrastructure.Type {    case "gcp":        project := gcp.Project{Name: namespace}        shoot, e = project.Spec(ev)        if e != nil {            return v1beta1.Shoot{}, e        }但这不起作用,有什么想法我该怎么做吗?
查看完整描述

1 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

但它不起作用


它没有指定,但我假设依赖注入不起作用。


注入至少需要两种不同的实体类型。一个被注射,第二个是接受注射的目标。


在您的情况下,您只有一个 - 以两种形式实现的注入gcp和azure.


您需要添加一个包含注入接口的目标:


type Target struct {

    Specer Shooter

}


func (t *Target) DoWork() {

   // here you can use t.Specer.Spec() without knowing implementation details

}

现在您可以Target使用 DI 创建:


func NewTarget(specer Shooter) *Target{

        return &Target{

          Specer: specer,

        } 

}

您的代码通常决定所有使用的类型并将它们注入(调用NewTarget())非常接近Composition Root中的应用程序启动


更新:


接口也可以注入函数。它也是依赖注入:


func kind(ev v1alpha1.Ev, namespace string, specer Shooter) (v1beta1.Shoot, error) {

   ...

   shoot, e = specer.Spec(ev)

   ...

}

这是称为服务定位器的模式的替代方案:


func kind(ev v1alpha1.Ev, namespace string) (v1beta1.Shoot, error) {

   ...

   specer := factory.GetSpecer()

   shoot, e = specer.Spec(ev)

   ...

}

服务定位器通常称为反模式。


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信