di

package module
v0.0.0-...-8e912d0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2015 License: ISC Imports: 3 Imported by: 0

README

go-di

Dependency Injection container library for golang.

https://github.com/AtsushiSuzuki/go-di

http://gidoc.org/github.com/AtsushiSuzuki/go-di

Features

  • Register type/value to container, retrieve registered instance by type name.
  • Set tag (alias) to type/value.
  • Inject struct field by struct tag.
  • Hierarchical container.
  • Manage instance lifetime by container. (Transient, Scoped, Singleton)

Example

package main

import "fmt"
import "github.com/AtsushiSuzuki/go-di"

// define inteface "Logger" and struct "myLogger"
type Logger interface {
    Log(message string)
}

type myLogger struct {
}

func (this *myLogger) Log(message string) {
    fmt.Println(message)
}

// define struct "myModule"
type myModule struct {
    Logger Logger `di:"logger"` // declare dependency to `logger`
}

func (this *myModule) DoWork(name string) {
    this.Logger.Log("Hello, " + name)
}

// register types
func init() {
    di.Registry.RegisterType(&myLogger{}, di.Transient)
    di.Registry.RegisterType(&myModule{}, di.Transient)
}

func main() {
    c := di.Registry.NewScope()
    c.Use("logger", "*main.myLogger")
    c.Use("module", "*main.myModule")

    v, _ := c.Resolve("module")
    v.(*myModule).DoWork("world")

    // Output:
    // Hello, world
}

API document

see godoc (http://godoc.org/github.com/AtsushiSuzuki/go-di).

Limitation

  • Requires type registration by hand.
  • No constructor injection.
  • No property injection.

TODOs

  • Better Container.RegisterFactory API.
  • Multithreading test.
  • Refactor lockings.
  • Check for other DI libraries.

License

ISC (http://opensource.org/licenses/ISC)

Documentation

Overview

Package `di` implements basic dependency injection (DI) container.

Example
package main

import "fmt"
import "github.com/AtsushiSuzuki/go-di"

type Logger interface {
	Log(message string)
}

type myLogger struct {
}

func (this *myLogger) Log(message string) {
	fmt.Println(message)
}

type myModule struct {
	Logger Logger `di:"logger"`
}

func (this *myModule) DoWork(name string) {
	this.Logger.Log("Hello, " + name)
}

func init() {
	di.Registry.RegisterType(&myLogger{}, di.Transient)
	di.Registry.RegisterType(&myModule{}, di.Transient)
}

func main() {
	c := di.Registry.NewScope()
	c.Use("logger", "*di_test.myLogger")
	c.Use("module", "*di_test.myModule")

	v, _ := c.Resolve("module")
	v.(*myModule).DoWork("world")

}
Output:
Hello, world
Example (Simple)
package main

import "fmt"
import "github.com/AtsushiSuzuki/go-di"

type MyStruct struct {
}

func main() {
	c := di.Registry.NewScope()
	c.RegisterType(&MyStruct{}, di.Transient)

	v, _ := c.Resolve("*di_test.MyStruct")
	fmt.Printf("v: %v (%T)", v, v)

}
Output:
v: &{} (*di_test.MyStruct)

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNoMatchingTag error = fmt.Errorf("no matching tag found")

Functions

This section is empty.

Types

type Constructor

type Constructor func(c Container) (interface{}, error)

`Constructor` is generic function type to create instance.

`Container` does not support constructor injection. Instead, you can use supplied `Container` to wire up your instance's dependency.

type Container

type Container interface {
	// `NewScope` creates new scoped container from parent container.
	//
	// Created scope inherits type registrations from it's parent.
	NewScope() Container

	// `RegisterType` registers type (`reflect.TypeOf(v)`) for
	// it's type name (`reflect.TypeOf(v).String`).
	//
	// When resolved, new zero/nil instance is created.
	// If type is pointer, type is resolved as an pointer points to
	// newly created element instead of nil pointer.
	//
	// If created instance is struct, it's field with
	// tag `di:"<tag>"` will be injected. see `Inject`.
	RegisterType(v interface{}, lifetime Lifetime)

	// `RegisterValue` registers supplied value `v` for
	// it's type name.
	RegisterValue(v interface{})

	// `RegisterFactory` registers factory method for type name of `v`.
	//
	// You can optionally use destructor. If supplied, `dtor` is called
	// for each resolved instance when asociated container is `Close`ed.
	//
	// TODO: inspect type name from constructor return value
	RegisterFactory(v interface{}, ctor Constructor, dtor Destructor, lifetime Lifetime)

	// `Use` sets an alias for other tag or type name.
	Use(tag string, tagOrTypeName string)

	// `UseType` registers type for specified tag.
	//
	// See `RegisterType`.
	UseType(tag string, v interface{}, lifetime Lifetime)

	// `UseValue` registers value for specified tag.
	//
	// See `RegisterValue`
	UseValue(tag string, v interface{})

	// `UseFactory` registers factory method for specified tag.
	//
	// See `RegisterFactory`.
	UseFactory(tag string, ctor Constructor, dtor Destructor, lifetime Lifetime)

	// `Resolve` returns instance for specified tag.
	//
	// If multiple type is registered for tag,
	// `Resolve` returns instance of last registered type.
	//
	// If no type is registered for tag, returns `ErrNoMatchingTag`.
	Resolve(tag string) (interface{}, error)

	// `ResolveAll` returns slice of instances for specified tag.
	ResolveAll(tag string) ([]interface{}, error)

	// `Inject` fills struct `v`'s fields with resolved instances
	// if field is tagged with `di:"<tag>"`
	Inject(v interface{}) error

	// `Close` invokes destructors for all instances resolved by
	// the container.
	Close() error
}

`Container` is type registry and dependency resolver.

You can use `RegisterType`, `RegisterValue` or `RegisterFactory` to register types to the container, and then use `Resolve` to obtain an registered instance.

`Container` instance is obtained by `Registry.NewScope()`.

var Registry Container = newContainer(nil)

`Registry` is global registry of types being resolved by containers.

type Destructor

type Destructor func(i interface{}) error

`Destructor` is cleanup function for created instance.

type Lifetime

type Lifetime int

`Lifetime` represents lifetime of instance resolved by container.

const (
	// `Transient` lifetime specifies that instances should
	// be created each time container resolves dependency.
	Transient Lifetime = iota

	// `Scoped` lifetime specifies that the instance should be reused
	// by the same container.
	Scoped

	// `Singleton` lifetime specifies that the instance should be
	// reused for process lifetime.
	Singleton
)

Jump to

Keyboard shortcuts

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