di: github.com/sarulabs/di Index | Files

package di

import "github.com/sarulabs/di"


Package Files

builder.go container.go containerCore.go containerGetter.go containerInterface.go containerLineage.go containerSlayer.go containerUnscopedGetter.go definition.go http.go scope.go utils.go


const App = "app"

App is the name of the application scope.

const Request = "request"

Request is the name of the request scope.

const SubRequest = "subrequest"

SubRequest is the name of the subrequest scope.


var C = func(i interface{}) Container {
    if c, ok := i.(Container); ok {
        return c

    r, ok := i.(*http.Request)
    if !ok {
        panic("could not get the container with C()")

    c, ok := r.Context().Value(ContainerKey("di")).(Container)
    if !ok {
        panic("could not get the container from the given *http.Request")

    return c

C retrieves a Container from an interface. The function panics if the Container can not be retrieved.

The interface can be : - a Container - an *http.Request containing a Container in its context.Context

for the ContainerKey("di") key.

The function can be changed to match the needs of your application.

func Get Uses

func Get(i interface{}, name string) interface{}

Get is a shortcut for C(i).Get(name).

func HTTPMiddleware Uses

func HTTPMiddleware(h http.HandlerFunc, app Container, logFunc func(msg string)) http.HandlerFunc

HTTPMiddleware adds a container in the request context.

The container injected in each request, is a new sub-container of the app container given as parameter.

It can panic, so it should be used with another middleware to recover from the panic, and to log the error.

It uses logFunc, a function that can log an error. logFunc is used to log the errors during the container deletion.

type Builder Uses

type Builder struct {
    // contains filtered or unexported fields

Builder can be used to create a Container. The Builder should be created with NewBuilder. Then you can add definitions with the Add method, and finally build the Container with the Build method.

func NewBuilder Uses

func NewBuilder(scopes ...string) (*Builder, error)

NewBuilder is the only way to create a working Builder. It initializes a Builder with a list of scopes. The scopes are ordered from the most generic to the most specific. If no scope is provided, the default scopes are used: [App, Request, SubRequest] It can return an error if the scopes are not valid.

func (*Builder) Add Uses

func (b *Builder) Add(defs ...Def) error

Add adds one or more definitions in the Builder. It returns an error if a definition can not be added. If a definition with the same name has already been added, it will be replaced by the new one, as if the first one never existed.

func (*Builder) Build Uses

func (b *Builder) Build() Container

Build creates a Container in the most generic scope with all the definitions registered in the Builder.

func (*Builder) Definitions Uses

func (b *Builder) Definitions() DefMap

Definitions returns a map with the all the objects definitions registered with the Add method. The key of the map is the name of the Definition.

func (*Builder) IsDefined Uses

func (b *Builder) IsDefined(name string) bool

IsDefined returns true if there is a definition with the given name.

func (*Builder) Scopes Uses

func (b *Builder) Scopes() ScopeList

Scopes returns the list of available scopes.

func (*Builder) Set Uses

func (b *Builder) Set(name string, obj interface{}) error

Set is a shortcut to add a definition for an already built object.

type Container Uses

type Container interface {
    // Definition returns the map of the available definitions ordered by name.
    // These definitions represent all the objects that this Container can build.
    Definitions() map[string]Def

    // Scope returns the Container scope.
    Scope() string

    // Scopes returns the list of available scopes.
    Scopes() []string

    // ParentScopes returns the list of scopes that are more generic than the Container scope.
    ParentScopes() []string

    // SubScopes returns the list of scopes that are more specific than the Container scope.
    SubScopes() []string

    // Parent returns the parent Container.
    Parent() Container

    // SubContainer creates a new Container in the next sub-scope
    // that will have this Container as parent.
    SubContainer() (Container, error)

    // SafeGet retrieves an object from the Container.
    // The object has to belong to this scope or a more generic one.
    // If the object does not already exist, it is created and saved in the Container.
    // If the object can not be created, it returns an error.
    SafeGet(name string) (interface{}, error)

    // Get is similar to SafeGet but it does not return the error.
    // Instead it panics.
    Get(name string) interface{}

    // Fill is similar to SafeGet but it does not return the object.
    // Instead it fills the provided object with the value returned by SafeGet.
    // The provided object must be a pointer to the value returned by SafeGet.
    Fill(name string, dst interface{}) error

    // UnscopedSafeGet retrieves an object from the Container, like SafeGet.
    // The difference is that the object can be retrieved
    // even if it belongs to a more specific scope.
    // To do so, UnscopedSafeGet creates a sub-container.
    // When the created object is no longer needed,
    // it is important to use the Clean method to delete this sub-container.
    UnscopedSafeGet(name string) (interface{}, error)

    // UnscopedGet is similar to UnscopedSafeGet but it does not return the error.
    // Instead it panics.
    UnscopedGet(name string) interface{}

    // UnscopedFill is similar to UnscopedSafeGet but copies the object in dst instead of returning it.
    UnscopedFill(name string, dst interface{}) error

    // Clean deletes the sub-container created by UnscopedSafeGet, UnscopedGet or UnscopedFill.
    Clean() error

    // DeleteWithSubContainers takes all the objects saved in this Container
    // and calls the Close function of their Definition on them.
    // It will also call DeleteWithSubContainers on each child and remove its reference in the parent Container.
    // After deletion, the Container can no longer be used.
    // The sub-containers are deleted even if they are still used in other goroutines.
    // It can cause errors. You may want to use the Delete method instead.
    DeleteWithSubContainers() error

    // Delete works like DeleteWithSubContainers if the Container does not have any child.
    // But if the Container has sub-containers, it will not be deleted right away.
    // The deletion only occurs when all the sub-containers have been deleted manually.
    // So you have to call Delete or DeleteWithSubContainers on all the sub-containers.
    Delete() error

    // IsClosed returns true if the Container has been deleted.
    IsClosed() bool

Container represents a dependency injection container. To create a Container, you should use a Builder or another Container.

A Container has a scope and may have a parent in a more generic scope and children in a more specific scope. Objects can be retrieved from the Container. If the requested object does not already exist in the Container, it is built thanks to the object definition. The following attempts to get this object will return the same object.

type ContainerKey Uses

type ContainerKey string

ContainerKey is a type that can be used to store a container in the context.Context of an http.Request. By default, it is used in the C function and the HTTPMiddleware.

type Def Uses

type Def struct {
    Build    func(ctn Container) (interface{}, error)
    Close    func(obj interface{}) error
    Name     string
    Scope    string
    Tags     []Tag
    Unshared bool

Def contains information to build and close an object inside a Container.

type DefMap Uses

type DefMap map[string]Def

DefMap is a collection of Def ordered by name.

func (DefMap) Copy Uses

func (m DefMap) Copy() DefMap

Copy returns a copy of the DefMap.

type ScopeList Uses

type ScopeList []string

ScopeList is a slice of scope.

func (ScopeList) Contains Uses

func (l ScopeList) Contains(scope string) bool

Contains returns true if the ScopeList contains the given scope.

func (ScopeList) Copy Uses

func (l ScopeList) Copy() ScopeList

Copy returns a copy of the ScopeList.

func (ScopeList) ParentScopes Uses

func (l ScopeList) ParentScopes(scope string) ScopeList

ParentScopes returns the scopes before the one given as parameter.

func (ScopeList) SubScopes Uses

func (l ScopeList) SubScopes(scope string) ScopeList

SubScopes returns the scopes after the one given as parameter.

type Tag Uses

type Tag struct {
    Name string
    Args map[string]string

Tag can contain more specific information about a Definition. It is useful to find a Definition thanks to its tags instead of its name.

Package di imports 7 packages (graph) and is imported by 4 packages. Updated 2020-05-14. Refresh now. Tools for package owners.