An application framework for Go that:
- Makes dependency injection easy.
- Eliminates the need for global state and
func init()
.
What is dependency injection?
Provide dependencies. For example, arguments needed by a function, instance variables needed to create an object...
No dependency injection
public SomeClass() {
myObject = Factory.getObject();
}
// from https://www.youtube.com/watch?v=LDGKQY8WJEM&t=254s&ab_channel=UberEngineering
func NewHandler() http.Handler {
logger := log.New(os.Stdout, "[ACME] ", 0)
// user logger
}
With dependency injection
public SomeClass (MyClass myObject) {
this.myObject = myObject;
}
// from https://www.youtube.com/watch?v=LDGKQY8WJEM&t=254s&ab_channel=UberEngineering
func NewHandler(logger *log.Logger) http.Handler {
// use logger
}
Why do we need dependency injection?
- Easy to test
- Decouple your objects
fx.New
// kick start your app
fx.New().Run()
fx.Provide
func Provide(constructors ...interface{})
Option
// Constructs type *C, depends on *A and *B.
func(*A, *B) *C
// Constructs type *C, depends on *A and *B, and indicates failure by
// returning an error.
func(*A, *B) (*C, error)
// Constructs types *B and *C, depends on *A, and can fail.
func(*A) (*B, *C, error)
A collection of constructors.
fx.New(
fx.Provide(http.NewServeMux),
).Run()
fx.Invoke
func fx.Invoke(funcs ...interface{}) fx.Option
A collection of how to kick-start the app.
fx.New(
fx.Provide(http.NewServeMux),
fx.Invoke(server.New)
).Run()
How does a function get invoked?
- Always executed when starting the application
- Executed in order
What inputs or outputs are needed for a function?
Arguments for these invocations are built using the constructors registered by Provide.
But how?
fx.Hook
Initialize callbacks when starting or stopping.
fx.Hook{
OnStart: func(ctx context.Context) error {
log.Println("Start running...")
},
OnStop: func(ctx context.Context) error {
log.Println("Stop running...")
},
}
fx.App
A instance of fx application, usually returned from
fx.New
fx.App.Start
and fx.App.Stop
Start/stop running your application.
app := fx.New()
app.Start()
app.Stop()
fx.App.Run
Running the application forever
app := fw.New()
app.Run()