Dependency Injection

Singleton Dependencies

A singleton dependency is exactly what it sounds like. It's a dependency, which is only instantiated once. That means the injected value will always be the same value originally created.

A good example for such a dependency is a database connection, or a cache.

package main

// imports

func main() {
  // The boolean defines whether the dependency is a singleton or not!
  mojito.Register(func() YourType {
    return YourType{}
  }, true)
}

YourType can be any type you want. It's the same type that you will have to use on injected fields and variables so the injector knows which dependency you want.

Transient Dependencies

A transient dependency is the opposite of a singleton dependency. It's a dependency, that will return a fresh value every time it's injected. The function you are passing to register the dependency can be treated like a factory function, that will produce the injected value.

A good example for a transient dependency are objects involving buffers or builders.

package main

// imports

func main() {
  // The boolean defines whether the dependency is transient or not!
  mojito.Register(func() YourType {
    return YourType{}
  }, false)
}

As you see, the example is almost identical!

Named Dependencies

For some types, you want to have more than one dependency. For example if you have more than one database connection, or more than one cache implementation. This is where named dependencies come in.

package main

// imports

func main() {
  mojito.RegisterNamed("type1", func() YourType {
    return YourType1{}
  }, true)

  mojito.RegisterNamed("type2", func() YourType {
    return YourType2{}
  }, true)
}

Like this, you register two different implementations of the same interface. Of course, you will have to resolve the dependency by its name instead of only its type! For example in handlers