inject

package module
v0.0.0-...-0e995e7 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2023 License: MIT Imports: 10 Imported by: 0

README

Inject

Dependency injection package for Go

Inject is a runtime dependency injection package for Go, based on struct tags and built on top of Go reflect package.

Some Features

  • Dependency injection rules in external yaml files
  • Custom struct factories, with singleton option
  • Default struct values, using struct tags and/or external file

Installation

Make sure you have Go installed (download). Version 1.18 or higher is required. Initialize your project by creating a folder and running go mod init github.com/your/repo inside the folder. Then install Inject with the go get command:

go get -u github.com/carlosranoya/inject

Example of Use 1

Create a main.go file and choose a package name. In this example, I choose package main.

package main

Import Inject pakage and other dependencies.

import (
    "fmt"
    "github.com/carlosranoya/inject"
)

Create an interface that will be injected by some struct instance.

type TestInterface interface {
    Test()
}

Create a struct that implements the interface.

type TestStruct struct {
    Message string
}
func (t *TestStruct) Test() {
    fmt.Println(t.Message)
}

At the main or init function, use Inject to register the interface and the injected struct.

func main() {

    fmt.Println("testing inject")

    inject.AddInterface[TestInterface]()

    inject.AddInjectable[TestStruct]()

Use Inject to register an yaml file that describe the relationship between interfaces and structs (details about this file below).

    inject.ImportConfig("config_1.yaml")

Create a struct that contains the interface and inject the interface field with the struct defined at "config_1.yaml" file.

    type TestContainer struct {
        Tester TestInterface `inject:"struct"`
    }
    container := TestContainer{}
    inject.Inject(&container)

Note that is necessary a tag definition to the struct's field intended to be injected. Make sure you pass a pointer to the Inject() function.

Finally, call the interface function to test the dependency injection and close the main function.

    container.Tester.Test()
}

Let's see the config_1.yaml file. It contains a section for "structs", identified as "injectables":

injectables:
  - name: TestStruct
    package: main
    params: 
      Message: "This message was defined at config_1.yaml"

This is a list with structs that will be injected at interface fields. Note that optionally there's a params field where we define values that will be set to struct fields. In this example, the struct TestStruct owns a string field named Message. Next, the interfaces section:

interfaces:
  - name: TestInterface
    injectable: TestStruct
    package: main

Here, we define the relationship between interfaces and injectable structs. The "package" parameter is fundamental, and it corresponds to the name of the package where interfaces and structs where defined. That's it.

Example of Use 2

This is very similar of last example, but instead of using a container struct (TestContainer) to be filled with a struct, we will define an inline interface variable, and it'll be instanciated as the struct defined at congif_1.yaml file.

    var i TestInterface
    i, err = InstaciateInjected[TestInterface]()
    i.Test()

Other Uses

Inject comes with another utilities. It may be used to define standard values for structs.

For example:

type TestStruct struct {
	NonParametrizedField string
	StringField          string `inject:"stringField" value:"teste"`
	IntField             int    `inject:"intField" value:"12"`
	BooleanField         bool   `inject:"booleanField" value:"true"`
}

At this case, we defined 3 fields that will be initializated with values defined at the struct's tags. The name after "inject:" must be any unique, not empty string, and is not relevant for this example. Next, create an instance using this Inject funcion:

testObject, err := inject.Instanciate[TestStruct]()

The names defined with Inject tags may be used to instanciate objects with map[string]any arguments.

type Developer struct {
   NonParametrizedField string
   StringField          string `inject:"name" value:"teste"`
   IntField             int    `inject:"age" value:"12"`
   BooleanField         bool   `inject:"likesGo" value:"false"`
}

var args map[string]any = map[string]any{
   "likesGo": true,
   "age":     27,
   "name": "Bob",
}

developer, err := inject.InstanciateWithArgs[Developer](args, false)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddFactory

func AddFactory[T any](obj *T, IsSingleton bool) error

func AddInjectable

func AddInjectable[T any]()

func AddInterface

func AddInterface[T any]()

func AddInterfacePointer

func AddInterfacePointer(pointer any)

func Describe

func Describe(v any, tabs string)

func GetInstance

func GetInstance[T any](args Args) *T

func ImportConfig

func ImportConfig(filename string)

func Inject

func Inject(obj any) error

func InjectWithArgs

func InjectWithArgs(obj any, args Args, doRemap bool) error

func InjectWithPositionalArgs

func InjectWithPositionalArgs(obj any, args []any) error

func InstaciateInjected

func InstaciateInjected[T interface{}]() (T, error)

func Instanciate

func Instanciate[T any]() (*T, error)

func InstanciateWithArgs

func InstanciateWithArgs[T any](args Args, remap bool) (*T, error)

func InstanciateWithPositionalArgs

func InstanciateWithPositionalArgs[T any](args []any) (*T, error)

func InstanciateWithRemap

func InstanciateWithRemap[T any]() (*T, error)

func ResetData

func ResetData()

Types

type Args

type Args map[string]any

Jump to

Keyboard shortcuts

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