Skip to content

Instantly share code, notes, and snippets.

@lsegal
Last active March 14, 2018 05:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lsegal/049be255a59ac407aa1f5b6c8d00c161 to your computer and use it in GitHub Desktop.
Save lsegal/049be255a59ac407aa1f5b6c8d00c161 to your computer and use it in GitHub Desktop.
Dependency Injection Problem (Go)

Dynamic Dependency Injection in Go

Implement a library that can perform Dependency Injection (DI) in Go.

Problem

Given any set of provider functions with interdependent arguments, write a Go program to call these functions in correct order such that all arguments are only initialized exactly 1 time and passed into all functions that might accept those types.

You can assume that all arguments are in turn created by at least one provider function. For simplicity, you can also assume that all arguments are pointers to struct types.

You cannot assume that provider functions will be any specific format. Your program should handle any function signature with supported types.

Example

We want the following code to initialize 3 struct objects, all of which depend on one another:

di.Invoke(NewA, NewB, NewC)

The structs and provider functions might be defined as follows:

type A struct {
  *B
  *C
}

type B {
  *C
}

type C struct {}

func NewA(b *B, c *C) *A {
  fmt.Println("INIT A")
  return &A{b, c}
}

func NewB(c *C) *B {
  fmt.Println("INIT B")
  return &B{c}
}

func NewC() *C {
  fmt.Println("INIT C")
  return &C{}
}

func main() {
  di.Invoke(NewA, NewB, NewC)
  // Output:
  // INIT C
  // INIT B
  // INIT A
}

Bonus Points

Allow non-pointer structs

func main() {
  di.Invoke(NewA)
}

func NewA() A {
  return A{}
}

Support static values passed into the Invoke() function

di.Invoke(NewA, NewB, C{})

Support interfaces

type NopCloser struct { }

func (n NopCloser) Close() error {
  return nil
}

func Start(c io.Closer) {
  // ...
}

func main() {
  di.Invoke(Start, NopCloser{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment