container

package module
v2.6.2 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2024 License: MIT Imports: 7 Imported by: 0

README

GoDoc Build Status Go Report Card Awesome Coverage Status

Container

A lightweight yet powerful IoC container for Go projects. It provides a simple, fluent and easy-to-use interface to make dependency injection in GoLang easier. Atrico fork adds "lazy" creation of singletons and Container as an interface (not a global)

Documentation

Required Go Versions

It requires Go v1.11 or newer versions.

Installation

To install this package, run the following command in the root of your project.

go get gitlab.com/atrico/container
Introduction

GoLobby Container like any other IoC container is used to bind abstractions to their implementations. Binding is a process of introducing an IoC container that which concrete (implementation) is appropriate for an abstraction. In this process, you also determine how it must be resolved, singleton or transient. In singleton binding, the container provides an instance once and returns it for each request. In transient binding, the container always returns a brand new instance for each request. After the binding process, you can ask the IoC container to get the appropriate implementation of the abstraction that your code depends on. In this case, your code depends on abstractions, not implementations.

Create container
c := container.NewContainer()
Binding
Singleton

Singleton binding using Container:

c.Singleton(func() Abstraction {
  return Implementation
})

It takes a resolver function which its return type is the abstraction and the function body configures the related concrete (implementation) and returns it.

Example for a singleton binding:

c.Singleton(func() Database {
  return &MySQL{}
})
Transient

Transient binding is also similar to singleton binding.

Example for a transient binding:

c.Transient(func() Shape {
  return &Rectangle{}
})
Resolving

Container resolves the dependencies with the method make().

Using References

One way to get the appropriate implementation you need is to declare an instance of the abstraction type and pass its reference to Container this way:

var a Abstraction
c.Make(&a)
// "a" will be implementation of the Abstraction

Example:

var m Mailer
c.Make(&m)
m.Send("[email protected]", "Hello Milad!")
Using Closures

Another way to resolve the dependencies is by using a function (receiver) that its arguments are the abstractions you need. Container will invoke the function and pass the related implementations for each abstraction.

c.Make(func(a Abstraction) {
  // "a" will be implementation of the Abstraction
})

Example:

c.Make(func(db Database) {
  // "db" will be the instance of MySQL
  db.Query("...")
})

You can also resolve multiple abstractions this way:

c.Make(func(db Database, s Shape) {
  db.Query("...")
  s.Area()
})
Binding time

You can also resolve a dependency at the binding time in your resolver function like the following example.

// Bind Config to JsonConfig
c.Singleton(func() Config {
    return &JsonConfig{...}
})

// Bind Database to MySQL
c.Singleton(func(c Config) Database {
    // "c" will be the instance of JsonConfig
    return &MySQL{
        Username: c.Get("DB_USERNAME"),
        Password: c.Get("DB_PASSWORD"),
    }
})

Notice: You can only resolve the dependencies in a binding resolver function that has already bound.

Usage Tips
Performance

The package Container inevitably uses reflection in binding and resolving processes. If performance is a concern, you should use this package more carefully. Try to bind and resolve the dependencies out of the processes that are going to run many times (for example, on each request), put it where that run only once when you run your applications like main and init functions.

License

GoLobby Container is released under the MIT License. Atrico-go container follows this license

Documentation

Overview

Package container provides an IoC container for Go projects. It provides simple, fluent and easy-to-use interface to make dependency injection in GoLang easier.

Package container provides an IoC container for Go projects. It provides simple, fluent and easy-to-use interface to make dependency injection in GoLang easier.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BindInfo added in v2.5.0

type BindInfo struct {
	DefaultTo string
	Transient bool
	Anonymous bool
}

type Config

type Config struct {
	// contains filtered or unexported fields
}

type Configurator

type Configurator func(config *Config)
var Default Configurator = func(config *Config) {
	config.isDefault = true
}
var Duplicate Configurator = func(config *Config) {
	config.duplicate = true
}
var NoName Configurator = func(config *Config) {
	config.name = ""
}
var Singleton Configurator = func(config *Config) {
	config.transient = false
}
var Transient Configurator = func(config *Config) {
	config.transient = true
}

func IsDefault added in v2.6.1

func IsDefault(isDefault bool) Configurator

func Name

func Name(name string) Configurator

type Container

type Container interface {
	// Resolve will resolve the dependency and return a appropriate concrete of the given abstraction.
	// It can take an abstraction (interface reference) and fill it with the related implementation.
	// It also can take a function (receiver) with one or more arguments of the abstractions (interfaces) that need to be
	// resolved, Container will invoke the receiver function and pass the related implementations.
	Resolve(receiver any)
	// ResolveByName will resolve the named dependency and return a appropriate concrete of the given abstraction.
	// It can take an abstraction (interface reference) and fill it with the related implementation.
	// It also can take a function (receiver) with one or more arguments of the abstractions (interfaces) that need to be
	// resolved, Container will invoke the receiver function and pass the related implementations.
	ResolveByName(name string, receiver any)
	// ResolveByNameOrDefault will resolve the named dependency and return a appropriate concrete of the given abstraction.
	// If named value doesn't exist, default value will be returned
	ResolveByNameOrDefault(name string, receiver any)

	// Status of the container, used for debugging
	Status() StatusType
	// Status as above but with reg ex filter
	StatusWithFilter(filter string) StatusType
}

Container interface for resolving registered concrete types

type ContainerBuilder

type ContainerBuilder interface {
	Container

	// Register factory function
	// It takes a resolver function which returns the concrete and its return type matches the abstraction (interface).
	// Function is called on Resolve
	// The resolver function can have arguments of abstraction that are bound in Container.
	Register(resolver any, configurators ...Configurator) ContainerBuilder

	// Clear will empty the container and remove all the bindings.
	Clear()
}

ContainerBuilder interface for registering abstractions

func NewContainer

func NewContainer() ContainerBuilder

Create empty container Add container itself

type StatusType added in v2.5.0

type StatusType map[string]map[string]BindInfo

func (StatusType) String added in v2.5.0

func (s StatusType) String() string

func (StatusType) StringMl added in v2.5.0

func (s StatusType) StringMl() (lines []string)

Jump to

Keyboard shortcuts

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