-
Notifications
You must be signed in to change notification settings - Fork 223
Description
Is your feature request related to a problem? Please describe.
When a constructor needs dig.In (or dig.Out) but I want my
application code to depend on a plain struct (no dig import),
I have to add extra boilerplate: create a StructIn wrapper
with dig.In and then write a Fix function that maps it to
the plain struct.
This gets repetitive across modules and makes it harder to keep
the domain/app layer clean.
type StructIn struct {
dig.In
Buffer *bytes.Buffer
}
func Fix(st StructIn) Struct {
return Struct{
Buffer: st.Buffer,
}
}
Describe the solution you'd like
Add a small helper, for example:
dig.AsIn(T{})anddig.AsIn(reflect.TypeOf(T{}))
that returns a constructor function which:
- takes an auto generated
dig.Instruct with the same fields - returns
Twith fields copied over - can be passed directly to
c.Provide(...)
So the user can do:
c.Provide(dig.AsIn(Struct{}))
instead of defining StructIn and Fix.
Describe alternatives you've considered
- Current approach:
-
define
type StructIn struct { dig.In; ... } -
define
func Fix(StructIn) Struct -
provide
Fix
-
Generic does not help.
-
Code generation (too heavy for this small mapping and dig bases on reflection).
Is this a breaking change?
No. Existing APIs and behavior stay unchanged.
Additional context
Code example (old vs proposed) is below:
main.go
package main
import (
"bytes"
"fmt" "log"
"go.uber.org/dig")
// AsIn removes the need to create StructIn and Fix.
type StructIn struct {
dig.In
Buffer *bytes.Buffer
}
func Fix(st StructIn) Struct {
return Struct{
Buffer: st.Buffer,
}
}
func main() {
c := dig.New()
err := c.Provide(func() *bytes.Buffer {
return bytes.NewBufferString("old version")
})
checkErr(err)
err = c.Provide(Fix)
checkErr(err)
err = c.Invoke(Run)
checkErr(err)
// As in version
cWithAsIn := dig.New()
err = cWithAsIn.Provide(func() *bytes.Buffer {
return bytes.NewBufferString("AsIn version")
})
checkErr(err)
err = cWithAsIn.Provide(dig.AsIn(Struct{}))
checkErr(err)
err = cWithAsIn.Invoke(Run)
checkErr(err)
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
// Placed in separate module as fx docs recommend it.
// https://uber-go.github.io/fx/modules.html#packages
type Struct struct {
Buffer *bytes.Buffer
}
func Run(st Struct) {
if st.Buffer == nil {
log.Fatalf("struct should be filled\n")
}
fmt.Printf("struct is filled: %v\n", st)
}
go.mod
module ex
go 1.20
require go.uber.org/dig v1.19.0
replace go.uber.org/dig => github.com/maranqz/dig v0.0.0-20260101180718-ec25e1f28ca2