di

package
v2.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2018 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const App = "app"

App is the name of the application scope.

View Source
const Request = "request"

Request is the name of the request scope.

View Source
const SubRequest = "subrequest"

SubRequest is the name of the subrequest scope.

Variables

View Source
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.

Functions

func Get

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

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

func HTTPMiddleware

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.

Types

type Builder

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

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

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.

func (*Builder) Build

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

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

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

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

func (*Builder) Scopes

func (b *Builder) Scopes() ScopeList

Scopes returns the list of available scopes.

type Container

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

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

type Def struct {
	Name  string
	Scope string
	Build func(ctn Container) (interface{}, error)
	Close func(obj interface{}) error
}

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

type DefMap

type DefMap map[string]Def

DefMap is a collection of Def ordered by name.

func (DefMap) Copy

func (m DefMap) Copy() DefMap

Copy returns a copy of the DefMap.

type ScopeList

type ScopeList []string

ScopeList is a slice of scope.

func (ScopeList) Contains

func (l ScopeList) Contains(scope string) bool

Contains returns true if the ScopeList contains the given scope.

func (ScopeList) Copy

func (l ScopeList) Copy() ScopeList

Copy returns a copy of the ScopeList.

func (ScopeList) ParentScopes

func (l ScopeList) ParentScopes(scope string) ScopeList

ParentScopes returns the scopes before the one given as parameter.

func (ScopeList) SubScopes

func (l ScopeList) SubScopes(scope string) ScopeList

SubScopes returns the scopes after the one given as parameter.

Jump to

Keyboard shortcuts

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