uber-go / dig

A reflection based dependency injection toolkit for Go.
https://go.uber.org/dig
MIT License
3.85k stars 206 forks source link

dig.In help #338

Open New2Niu opened 2 years ago

New2Niu commented 2 years ago
package main

import (
    "fmt"
    "go.uber.org/dig"
)

type Animal interface {
    Say()
}

type Dog struct {
    Name string
}

// NewDog dig provider
func NewDog() *Dog {
    println("new dog")
    return &Dog{
        Name: "xiaohei",
    }
}

func (d *Dog) Say() {
    fmt.Printf("%s say\n", d.Name)
}

type Cat struct {
    Name string
}

func (c *Cat) Say() {
    fmt.Printf("%s say\n", c.Name)
}

// NewCat dig provider
func NewCat() *Cat {
    println("new cat")
    return &Cat{
        Name: "xiaohong",
    }
}

type Zoo struct {
    BlackDog *Dog
    RedCat   *Cat
}

type injector struct {
    dig.In
    BlackDog *Dog `name:"dog"`
    RedCat   *Cat `name:"cat"`
}

func NewZoo(inj injector) *Zoo {
    println("new zoo")

    return &Zoo{
        BlackDog: inj.BlackDog,
        RedCat:   inj.RedCat,
    }
}

func main() {

    container := dig.New()

    container.Provide(NewDog, dig.Name("dog"))
    container.Provide(NewCat, dig.Name("cat"))
    container.Provide(NewZoo)

    container.Invoke(func(z *Zoo) {
        println("----")
        z.RedCat.Say()
    })

}

As above, I must create injector struct as param to NewZoo. How can I simplify it.Like this

type Zoo struct {
    dig.In
    BlackDog *Dog `name:"dog"`
    RedCat   *Cat `name:"cat"`
}

//type injector struct {
//  dig.In
//  BlackDog *Dog `name:"dog"`
//  RedCat   *Cat `name:"cat"`
//}

func NewZoo(inj Zoo) *Zoo {
    println("new zoo")

    return &Zoo{
        BlackDog: inj.BlackDog,
        RedCat:   inj.RedCat,
    }
}
abhinav commented 2 years ago

Hello! We currently do not support this feature, but I think we might want to. This ties into two issue that have been discussed on the uber-go/fx project more: https://github.com/uber-go/fx/issues/725 and https://github.com/uber-go/fx/issues/726.

Dig currently prevents structs tagged with dig.In from being returned from a constructor. There could be two ways for us to solve this:

  1. Remove that restrictions. We'd have to be careful about this and evaluate the implications and possible misuses of it.
  2. Support tagging the struct as a dig.In temporarily and then letting the constructor return it (this will need https://github.com/uber-go/fx/issues/726).

We'll discuss this internally and try to find a long-term solution here.

Internal issue ref: GO-1394