Search code examples
godependency-injectioninversion-of-control

Dependency injection with interface in go


I have a struct StructDependingOnInterface which depends on MyInterface interface. I'd like the struct Implementation to be injected into bar when StructDependingOnInterface is instantiated.

I have tried doing this with facebookgo/inject library, but it seems like it doesn't work with interfaces. s.bar is always nil.

package main

import (
    "fmt"
    "log"

    "github.com/facebookgo/inject"
)

type MyInterface interface {
    Foo()
}

type Implementation struct{}

func (imp *Implementation) Foo() {
    fmt.Println("Hello")
}

type StructDependingOnInterface struct {
    bar MyInterface `inject:""`
}

func main() {
    var g inject.Graph

    err := g.Provide(
        &inject.Object{Value: &Implementation{}},
    )
    if err != nil {
        log.Fatal(err)
    }

    g.Populate()

    s := &StructDependingOnInterface{}
    s.bar.Foo()
}

Does the language go allows what I'm trying to do ?

Is there an alternative of facebookgo/inject that would fits my need ?


Solution

  • facebookgo/inject should be able to handle interfaces, look at the example in the link and how they use http.RoundTripper and http.DefaultTransport.

    First you need to export bar, i.e. changing it to Bar. Then you also need to pass s to Provide for g.Populate to then be able to set Bar.

    type StructDependingOnInterface struct {
        Bar MyInterface `inject:""`
    }
    
    func main() {
        var g inject.Graph
    
        s := &StructDependingOnInterface{}
        err := g.Provide(
            &inject.Object{Value: s},
            &inject.Object{Value: &Implementation{}},
        )
        if err != nil {
            log.Fatal(err)
        }
    
        if err := g.Populate(); err != nil {
             log.Fatal(err)
        }
    
        s.bar.Foo()
    }