go-dependency-injection

module
v0.0.0-...-fc0a20c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2025 License: MIT

README

go-dependency-injection

Dependency injection in Go

Motivation

I wanted a DI system that allowed solid typing using generics. I also wanted a way that I could do things like routing and CLI subcommands, so I created a way to register a group of types that could then be consumed by something like a router.

Examples

Simple example

package main

import (
	"context"

	"github.com/poy/go-dependency-injection/pkg/injection"
)

type A interface {
	A()
}

type B interface {
	B()
}

func init() {
	injection.Register[A](
		func(ctx context.Context) A {
			return &a{
				b: injection.Resolve[B](ctx),
			}
		},
	)
}

type a struct {
	b B
}

func (a *a) A() {
	println("A()")
	a.b.B()
}

func init() {
	injection.Register[B](
		func(ctx context.Context) B {
			return &b{}
		},
	)
}

type b struct {
}

func (b *b) B() {
	println("B()")
}

func main() {
	ctx := injection.WithInjection(context.Background())
	a := injection.Resolve[A](ctx)
	a.A()
}

CLI with subcommands

This example demonstrates a CLI with subcommands that register themselves. This doesn't show it, however each subcommand should/could be its own file.

package main

import (
	"context"
	"os"

	"github.com/poy/go-dependency-injection/pkg/injection"
	"github.com/spf13/cobra"
)

func main() {
	ctx := injection.WithInjection(context.Background())
	if err := BuildRoot(ctx).ExecuteContext(ctx); err != nil {
		os.Exit(1)
	}
}

type SubCommand *cobra.Command

func BuildRoot(ctx context.Context) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "some-cli",
		Short: "Some CLI",
		Long:  "Some CLI",
		RunE: func(cmd *cobra.Command, args []string) error {
			return cmd.Help()
		},
	}

	for _, subCmd := range injection.Resolve[injection.Group[SubCommand]](ctx).Vals() {
		cmd.AddCommand(subCmd)
	}

	return cmd
}

func init() {
	injection.Register[injection.Group[SubCommand]](
		func(ctx context.Context) injection.Group[SubCommand] {
			return injection.AddToGroup(ctx, buildFooCommand(ctx))
		},
	)
}

func buildFooCommand(ctx context.Context) SubCommand {
	return &cobra.Command{
		Use:  "foo",
		Args: cobra.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			println("Foo")
			return nil
		},
	}
}

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL