Skip to content
This repository was archived by the owner on Feb 25, 2024. It is now read-only.

noartem/godi

Repository files navigation

Godi PkgGoDev

Simple Golang DI container based on reflection

Examples: examples folder

Full example: noartem/godi-example

Godoc: pkg.go.dev

Get started

  1. Install godi go get github.com/noartem/godi

  2. Create interfaces and beans implementing these interfaces:

    type IName interface {
        NewName() string
    }
    
    type Name struct {}
    
    func (name *Name) Generate() string {
        return "Lorem Ipsumovich"
    }
  3. Create bean factory:

    func NewName() IName {
        return &Name{ ... }
    }

    In factory, you can import other beans:

    func NewName(db IDatabase, log ILogger, ...) IName {
        return &Name{
            db: db,
            log: log,
        }
    }

    Factories can also return BeanOptions and/or errors:

    func NewName() (IName, *godi.BeanOptions, error) {
        err := someFunc()
        if err != nil {
            return &Name{}, nil, err
        }
    
        options := &godi.BeanOptions{
            Type: godi.Singleton, // Default: godi.Prototype
        }
    
        name := &Name{}
    
        return name, options, nil
    }

    or func NewName() (IName, error) {}, or func NewName() (IName, *godi.BeanOptions)

  4. Create DI container and register factories:

    func main() {
        c, err := godi.NewContainer(NewName, NewRandom, NewFoo, ...)
        if err != nil {
            panic(err)
        }
    
        ...
  5. Get bean from a container:

        // get bean by interface name
        nameBean, err := c.Get("IName")
        if err != nil {
            panic(err)
        }
    
        name, ok := nameBean.(IName)
        if !ok {
            panic("Invalid name bean")
        }
    
        // now you can use IName
        fmt.Println(name.Generate())
    }
  6. Build your architecture based on IOC with DI

  7. Profit! See another examples in examples folder

Other features

  1. Static beans. Can be used for sharing constants (global config, secrets, e.t.c.)

    1. Create a custom type

      type IPassword string
    2. Create implementations

      var defaultPassword IPassword = "qwerty123"
    3. Register

      godi.NewContainer(defaultPassword)

      Constant will be registered as IPassword

    4. Use it

      func NewName(password IPassword) IName {...}
  2. Structures with dependencies in Input. If you don't want to write boilerplate code creating structure with all input dependency, you can write them in structure with InStruct field and require this as input in factory.

    1. Create structure based on godi.InStruct and add your dependencies:

      import "github.com/noartem/godi"
      
      type deps struct {
         godi.InStruct
      
         Name IName
         Config IConfig
         Random IRandom
      }
    2. Require this structure in factory:

      func NewHello(deps deps) IHello { ... }
    3. Use your dependencies:

      func NewHello(deps deps) IHello {
         log.Println(deps.Name.GenerateName())
         log.Println(deps.Config)
         log.Println(deps.Random.Intn(1337))
      }