uber-go / dig

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

Introduce Callback Functions for Constructor & Decorator Calls #377

Closed JacobOaks closed 1 year ago

JacobOaks commented 1 year ago

Recently folks have been asking for more visiblity into what constructors and decorators actually get called, especially Fx users (https://github.com/uber-go/fx/issues/1039).

This PR allows users to provide callback functions for Dig to call when it invokes a constructor or decorator. Dig will pass along some basic information to the callback function: the name of the function, and the error it returned if any.

Users can provide a callback by using the two new APIs, dig.WithProviderCallback and dig.WithDecoratorCallback, which return a type implementing both dig.ProvideOption and dig.DecorateOption. For example, this code prints a simple message when myFunc and myDecorator are called (presumably defined elsewhere):

c := dig.New()
myCallback := func(ci CallbackInfo) {
    var errorAdd string
    if ci.Error != nil {
        errorAdd = fmt.Sprintf("with error: %v", ci.Error)
    }
    fmt.Printf("%q finished%v", ci.Name, errorAdd)
}
c.Provide(myFunc, WithProviderCallback(myCallback))
c.Decorate(myDecorator, WithDecoratorCallback(myCallback))

We can discuss Fx-side consumption of this functionality to aid observability in this way and help identify dead code, but one idea is to register callback functions that will generate new Fx events when constructors and decorators get called. I wrote a prototype implementation of this idea for Fx, and then wrote a demo showing how this can help identify dead code.

Internal Ref: GO-1873

codecov[bot] commented 1 year ago

Codecov Report

Merging #377 (6ec4a1a) into master (87cf89e) will increase coverage by 0.03%. The diff coverage is 100.00%.

:exclamation: Current head 6ec4a1a differs from pull request most recent head e281032. Consider uploading reports for the commit e281032 to get more accurate results

@@            Coverage Diff             @@
##           master     #377      +/-   ##
==========================================
+ Coverage   98.35%   98.38%   +0.03%     
==========================================
  Files          21       22       +1     
  Lines        1458     1490      +32     
==========================================
+ Hits         1434     1466      +32     
  Misses         15       15              
  Partials        9        9              
Impacted Files Coverage Δ
callback.go 100.00% <100.00%> (ø)
constructor.go 97.46% <100.00%> (+0.24%) :arrow_up:
decorate.go 100.00% <100.00%> (ø)
provide.go 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more