猿问

使用 go 接口进行依赖注入

在阅读了一些关于它的文档后,我试图通过 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#L16


func 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

        }

但这不起作用,有什么想法我该怎么做吗?


蛊毒传说
浏览 82回答 1
1回答

一只甜甜圈

但它不起作用它没有指定,但我假设依赖注入不起作用。注入至少需要两种不同的实体类型。一个被注射,第二个是接受注射的目标。在您的情况下,您只有一个 - 以两种形式实现的注入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)   ...}服务定位器通常称为反模式。
随时随地看视频慕课网APP

相关分类

Go
我要回答