uber-go / fx

A dependency injection based application framework for Go.
https://uber-go.github.io/fx/
MIT License
5.48k stars 283 forks source link

Support multiple ResultTags annotations #1210

Open jmmills opened 1 month ago

jmmills commented 1 month ago

As multiple  As annotations are supported, it would make sense to support multiple ResultTag annotations.

Currently this code fails with cannot apply more than one line of ResultTags

func main() {
    app := fx.New(
        fx.Provide(
            fx.Annotate(
                func() *bytes.Buffer {
                    return bytes.NewBuffer([]byte("Hello!"))
                },
                fx.ResultTags(`name:"a"`),
                fx.ResultTags(`name:"b"`),
            ),
        ),
        fx.Invoke(
            fx.Annotate(
                func(a, b *bytes.Buffer) {
                    fmt.Println(a.String())
                    fmt.Println(b.String())
                },
                fx.ParamTags(
                    `name:"a"`,
                    `name:"b"`,
                ),
            ),
        ),
    )
    app.Run()
}

A work-around is possible by providing multiple copies of the same instance of a type, however it is less intuitive.

fx.Provide(
    fx.Annotate(
        func() (*bytes.Buffer, *bytes.Buffer) {
            a := bytes.NewBuffer([]byte("Hello!"))
            b := a
            return a, b
        },
        fx.ResultTags(`name:"a"`, `name:"b"`),
    ),
)

Is this a breaking change? It should not be a breaking change as nothing (sans tests) should rely on app failure for multiple result tag annotations.