Decorate multiple times does not work
yiminc opened this issue · 7 comments
Apply fx.Decorate() to different fx.Module() at different level of the dependency graph. Only one of them take effect.
Below is a simple code where fx.Decorate() is applied to both FooServiceModule and TestModule. I would expect the logger to have both tag, but it would have only one tag. Comment out either one of the fx.Decorate() will make the other apply.
package main
import (
"context"
"go.uber.org/fx"
"go.uber.org/zap"
)
func NewLog() (*zap.Logger, error) {
return zap.NewDevelopment()
}
var LogModule = fx.Options(
fx.Provide(NewLog),
)
type fooService struct {
logger *zap.Logger
}
func NewFooService(logger *zap.Logger) *fooService {
return &fooService{logger: logger}
}
func (s *fooService) Start() error {
s.logger.Info("start foo service")
return nil
}
var FooServiceModule = fx.Module(
"fooService",
fx.Provide(NewFooService),
fx.Decorate(func(logger *zap.Logger) *zap.Logger {return logger.With(zap.String("service", "foo"))}),
fx.Invoke(fooLifecycleHooks),
)
func fooLifecycleHooks(
lc fx.Lifecycle,
service *fooService,
) {
lc.Append(fx.Hook{
OnStart: func(context.Context) error {
return service.Start()
},
})
}
var ServerModule = fx.Module(
"server",
LogModule,
FooServiceModule,
)
var TestModule = fx.Module(
"test",
ServerModule,
fx.Decorate(func(logger *zap.Logger) *zap.Logger {return logger.With(zap.String("test", "true"))}),
)
func main() {
app := fx.New(
TestModule,
fx.NopLogger,
)
app.Start(context.Background())
}
Found the root cause to be an issue in Dig. See uber-go/dig#321.
@yiminc uber-go/dig#322 should fix this. If you pin Dig to github.com/sywhang/dig@multiple-decorates
, you should see the output you are expecting to see:
2022-02-17T15:46:57.494-0800 INFO ym/main.go:27 start foo service {"test": "true", "service": "foo"}
@sywhang , thank you so much, didn't expected the fix comes this fast.
I can confirm that the fix works.
Thanks for confirming!
Closed by uber-go/dig#322.