8000 GitHub - jcooky/go-din: A lightweight dependency injection container for Go applications, leveraging Go generics for type-safe dependency management.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ go-din Public

A lightweight dependency injection container for Go applications, leveraging Go generics for type-safe dependency management.

License

Notifications You must be signed in to change notification settings

jcooky/go-din

Repository files navigation

go-din Go Test & Lint

A lightweight dependency injection container for Go applications, leveraging Go generics for type-safe dependency management.

Features

  • Type-safe dependency injection using Go generics
  • Simple API for registering, retrieving, and managing dependencies
  • Support for different environments (production, testing)
  • Easy mocking of dependencies for testing
  • Both named and type-based dependency resolution

Installation

go get -u github.com/jcooky/go-din

How to use

Creating a Container

// Create a new container with production environment
container := din.NewContainer(din.EnvProd)

// Or for testing
container := din.NewContainer(din.EnvTest)

Registering Dependencies

You can register dependencies in two ways:

  1. By type (recommended):
// Register a dependency factory for type A
din.RegisterT(func(ctx context.Context, c *din.Container) (A, error) {
    return &a{
        foo: "foo",
    }, nil
})
  1. By name:
// Register a dependency with a custom name
din.Register(din.Name("myService"), func(ctx context.Context, c *din.Container) (any, error) {
    return &MyService{}, nil
})

Retrieving Dependencies

Retrieve dependencies type-safely:

// Get by type (recommended)
a, err := din.GetT[A](ctx, container)
if err != nil {
    // Handle error
}

// Or with panic on error
a := din.MustGetT[A](ctx, container)

// Get by name
a, err := din.Get[A](ctx, container, din.Name("myService"))
if err != nil {
    // Handle error
}

Managing Dependencies with Dependencies

Dependencies can depend on other dependencies:

din.RegisterT(func(ctx context.Context, c *din.Container) (*B, error) {
    // Get dependency A
    a := din.MustGetT[A](ctx, c)
    
    // Create B with A as a dependency
    b := &B{
        bar: "bar",
        a:   a,
    }

    return b, nil
})

Testing with Mocks

Easily replace dependencies for testing:

// Create test container
container := din.NewContainer(din.EnvTest)

// Set mock implementation
din.SetT[ServiceInterface](container, &MockService{})

// Get component with mocked dependency
component, err := din.GetT[*Component](ctx, container)

Example

// Define interfaces and implementations
type A interface {
    Foo() string
}

type a struct {
    foo string
}

func (a *a) Foo() string {
    return a.foo
}

// Register implementation
func init() {
    din.RegisterT(func(ctx context.Context, c *din.Container) (A, error) {
        return &a{foo: "foo"}, nil
    })
}

// Component that depends on A
type B struct {
    bar string
    a   A
}

func (b *B) Bar() string {
    return fmt.Sprintf("%s and %s", b.a.Foo(), b.bar)
}

// Register component with dependency
func init() {
    din.RegisterT(func(ctx context.Context, c *din.Container) (*B, error) {
        a := din.MustGetT[A](ctx, c)
        b := &B{
            bar: "bar",
            a:   a,
        }
        return b, nil
    })
}

// Usage
func main() {
    ctx := context.Background()
    container := din.NewContainer(din.EnvProd)
    
    b, err := din.GetT[*B](ctx, container)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(b.Bar()) // Output: foo and bar
}

See more detailed examples in the examples directory.

License

MIT License

About

A lightweight dependency injection container for Go applications, leveraging Go generics for type-safe dependency management.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published
0