fx

An application framework for Go that:
  • Makes dependency injection easy.
  • Eliminates the need for global state and func init().

What is dependency injection?

Just fancy words
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

func New(opts ...Option) *App
// 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()

Example

 

Source