Convert Figma logo to code with AI

uber-go logofx

A dependency injection based application framework for Go.

5,648
287
5,648
55

Top Related Projects

26,478

A standard library for microservices.

12,864

Compile-time Dependency Injection for Go

1,801

⚙️ A dependency injection toolkit based on Go 1.18+ Generics.

1,406

Package inject provides a reflect based injector.

Quick Overview

Fx is a dependency injection system for Go. It provides a set of tools and patterns for building modular, maintainable, and testable applications by managing the lifecycle of objects and their dependencies.

Pros

  • Simplifies dependency management in large Go applications
  • Encourages modular and testable code structure
  • Supports both constructor and struct tag-based dependency injection
  • Integrates well with existing Go code and libraries

Cons

  • Introduces additional complexity for small projects
  • Requires a learning curve to understand and use effectively
  • May lead to increased compile times due to reflection
  • Can make debugging more challenging due to indirect object creation

Code Examples

  1. Basic dependency injection:
package main

import (
    "fmt"
    "go.uber.org/fx"
)

type Greeter struct {
    Name string
}

func NewGreeter() *Greeter {
    return &Greeter{Name: "World"}
}

func (g *Greeter) Greet() {
    fmt.Printf("Hello, %s!\n", g.Name)
}

func main() {
    fx.New(
        fx.Provide(NewGreeter),
        fx.Invoke(func(g *Greeter) {
            g.Greet()
        }),
    ).Run()
}
  1. Struct tag-based injection:
package main

import (
    "fmt"
    "go.uber.org/fx"
)

type Config struct {
    Port int
}

type Server struct {
    fx.In

    Config *Config `name:"serverConfig"`
}

func NewConfig() *Config {
    return &Config{Port: 8080}
}

func main() {
    fx.New(
        fx.Provide(
            fx.Annotated{
                Name: "serverConfig",
                Target: NewConfig,
            },
        ),
        fx.Invoke(func(s Server) {
            fmt.Printf("Server running on port %d\n", s.Config.Port)
        }),
    ).Run()
}
  1. Lifecycle management:
package main

import (
    "context"
    "fmt"
    "go.uber.org/fx"
)

type Resource struct{}

func NewResource() *Resource {
    return &Resource{}
}

func (r *Resource) Initialize(lc fx.Lifecycle) {
    lc.Append(fx.Hook{
        OnStart: func(context.Context) error {
            fmt.Println("Resource initialized")
            return nil
        },
        OnStop: func(context.Context) error {
            fmt.Println("Resource cleaned up")
            return nil
        },
    })
}

func main() {
    fx.New(
        fx.Provide(NewResource),
        fx.Invoke((*Resource).Initialize),
    ).Run()
}

Getting Started

To start using Fx in your Go project:

  1. Install Fx:

    go get go.uber.org/fx
    
  2. Import Fx in your main package:

    import "go.uber.org/fx"
    
  3. Define your dependencies and use fx.New() to create an application:

    func main() {
        fx.New(
            fx.Provide(
                NewConfig,
                NewDatabase,
                NewServer,
            ),
            fx.Invoke(StartServer),
        ).Run()
    }
    
  4. Run your application and Fx will manage the dependency graph and lifecycle of your objects.

Competitor Comparisons

26,478

A standard library for microservices.

Pros of kit

  • More comprehensive microservices toolkit with support for various transport protocols
  • Extensive documentation and examples for different use cases
  • Larger community and ecosystem of extensions

Cons of kit

  • Steeper learning curve due to its extensive feature set
  • More boilerplate code required for simple applications
  • Heavier dependency footprint

Code Comparison

kit example:

func main() {
    svc := service.New(logger, db)
    endpoints := endpoint.New(svc, logger)
    httpHandler := transport.NewHTTPHandler(endpoints, logger)
    http.ListenAndServe(":8080", httpHandler)
}

fx example:

func main() {
    fx.New(
        fx.Provide(
            NewLogger,
            NewDB,
            NewService,
            NewHTTPHandler,
        ),
        fx.Invoke(StartHTTPServer),
    ).Run()
}

kit focuses on explicit wiring of components, while fx uses dependency injection for a more concise setup. kit provides more flexibility in terms of transport protocols and middleware, but fx offers a simpler approach for smaller applications. Both libraries aim to improve the structure and maintainability of Go applications, with kit being more suited for complex microservices and fx for general-purpose dependency management.

12,864

Compile-time Dependency Injection for Go

Pros of Wire

  • Compile-time dependency injection, catching errors early
  • Generates code, avoiding runtime reflection for better performance
  • Simpler syntax with less boilerplate compared to fx

Cons of Wire

  • Requires a separate code generation step
  • Less flexibility for runtime configuration changes
  • Steeper learning curve for complex dependency graphs

Code Comparison

Wire:

func InitializeEvent() Event {
    wire.Build(NewEvent, NewGreeter, NewMessage)
    return Event{}
}

fx:

func main() {
    fx.New(
        fx.Provide(NewEvent, NewGreeter, NewMessage),
        fx.Invoke(func(e Event) {
            e.Start()
        }),
    ).Run()
}

Wire focuses on compile-time dependency injection, generating code to wire dependencies. It requires a separate build step but catches errors early and avoids runtime reflection.

fx, on the other hand, uses runtime dependency injection, offering more flexibility for configuration changes. It has a more declarative syntax and integrates well with other Uber Go libraries.

Both tools aim to simplify dependency management in Go applications, but they take different approaches. Wire is better suited for projects prioritizing compile-time safety and performance, while fx excels in scenarios requiring runtime flexibility and integration with other Uber Go ecosystem components.

1,801

⚙️ A dependency injection toolkit based on Go 1.18+ Generics.

Pros of do

  • Simpler API with less boilerplate code
  • Supports generics, allowing for type-safe dependency injection
  • Smaller codebase, potentially easier to understand and maintain

Cons of do

  • Less mature and less widely adopted compared to fx
  • Fewer advanced features and customization options
  • Limited documentation and community support

Code Comparison

fx:

var module = fx.Module("example",
    fx.Provide(
        NewConfig,
        NewLogger,
        NewService,
    ),
    fx.Invoke(Run),
)

do:

container := do.New()
container.Provide(NewConfig)
container.Provide(NewLogger)
container.Provide(NewService)
container.Invoke(Run)

Both fx and do are dependency injection frameworks for Go, but they differ in their approach and features. fx offers a more comprehensive solution with advanced features and extensive documentation, while do provides a simpler, more lightweight alternative with support for generics. The choice between the two depends on the project's complexity, team preferences, and specific requirements.

1,406

Package inject provides a reflect based injector.

Pros of inject

  • Simpler API with fewer concepts to learn
  • Lightweight and focused solely on dependency injection
  • More flexible in allowing manual object creation and injection

Cons of inject

  • Less feature-rich compared to fx's lifecycle management and module system
  • Not actively maintained (archived repository)
  • Limited support for advanced dependency resolution scenarios

Code Comparison

inject:

type App struct {
    Name string `inject:""`
    DB   *sql.DB `inject:""`
}

var app App
injector := inject.New()
injector.Provide(&app)
injector.Provide(db)
injector.Populate()

fx:

type App struct {
    Name string
    DB   *sql.DB
}

fx.New(
    fx.Provide(
        NewApp,
        NewDB,
    ),
    fx.Invoke(func(app *App) {
        // Use app
    }),
)

inject focuses on simple field injection, while fx uses constructor injection and offers more structured application composition. fx provides a more robust framework for managing dependencies and application lifecycle, whereas inject is a lighter-weight solution for basic dependency injection needs.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

:unicorn: Fx GoDoc Github release Build Status Coverage Status Go Report Card

Fx is a dependency injection system for Go.

Benefits

  • Eliminate globals: Fx helps you remove global state from your application. No more init() or global variables. Use Fx-managed singletons.
  • Code reuse: Fx lets teams within your organization build loosely-coupled and well-integrated shareable components.
  • Battle tested: Fx is the backbone of nearly all Go services at Uber.

See our docs to get started and/or learn more about Fx.

Installation

Use Go modules to install Fx in your application.

go get go.uber.org/fx@v1

Getting started

To get started with Fx, start here.

Stability

This library is v1 and follows SemVer strictly.

No breaking changes will be made to exported APIs before v2.0.0.

This project follows the Go Release Policy. Each major version of Go is supported until there are two newer major releases.

Stargazers over time

Stargazers over time