dependency_injection

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2022 License: MIT Imports: 4 Imported by: 3

README

go-di

Scope based dependency injection for golang

Content

How to install
go get -u github.com/ashkanabd/go-di
Features:
  • Easy to set up and use.
  • Scope based dependency injection like NestJS and .Net frameworks.
  • Able to integrate with golang popular frameworks like gin, fiber, etc.
  • Define your services once, use as much as you want.
  • Supports interface registration and can provide structs that implement registered interface.
  • Supports pointer registration.
  • Supports nested service resolving, regardless of lifetime (You have access to scope in providers).
  • Supports goroutines, no data race issues. Implemented with RWMutex to optimize performance.
How to use
1. Import go-di package:
import di "github.com/ashkanabd/go-di"
2. Initialize service collection:

At fist step you need to initialize service collection:

collection := di.InitServiceCollection()
3. Register your services in service collection:

You can register your service with 3 different lifetimes:

  1. Singleton: Services that will initialize once when requested and will retrieve whenever requested again
  2. Scoped: Services which will initialize once in the scope that requested and will be retrieved if the same scope requests. But if another scope requests same service, will be initialized again
  3. Transient: Services which will be initialized whenever requested using their providers.

If you want to register an interface, your provider function must return a pointer to the instance of a struct that implements the interface.

You can register your services with following functions:

// For singleton services
error := di.AddSingleton[ServiceType/ServiceInterface](collection, func (s *di.Scope) any {
   // provider of your service
   return ServiceType{}
})
// For scoped services
error := di.AddScoped[ServiceType/ServiceInterface](collection, func (s *di.Scope) any {
   // provider of your service
   return ServiceType{}
})
// For transient services
error := di.AddTransient[ServiceType/ServiceInterface](collection, func (s *di.Scope) any {
   // provider of your service
   return ServiceType{}
})
4. Lock your service collection:

In order to create scope from your service collection, you have to lock it to prevent adding more services while you are requesting for services.

collection.Lock()
5. Creating scope:

To get services which you registered before, you need to create a scope:

scope, error := collection.CreateScope()
6. Getting services:

Now you can get your services from dependency injection:

service, error := di.GetService[ServiceType](scope)
Examples

Here is implemented examples in different frameworks:

  1. Integration with golang built-in http web server: link
  2. Integration with gin framework: link
  3. Integration with fiber framework: link

Documentation

Index

Constants

View Source
const (
	// SINGLETON lifetime represent to the services which will initialize once when requested
	// and same instance will be retrieved whenever requested again in the entire application.
	SINGLETON = iota
	// SCOPED lifetime represent to the services that will initialize in every new scope when requested
	// and same value will be retrieved in if the same scope requests it.
	// Note that requesting same service in different scopes will cause initializing new instance.
	SCOPED
	// TRANSIENT lifetime represent to the services that will initialize whenever requested.
	TRANSIENT
)

Lifetimes

Variables

This section is empty.

Functions

func AddScoped

func AddScoped[T any](collection *ServiceCollection, provider func(s *Scope) any) error

AddScoped registers a service as scoped

func AddSingleton

func AddSingleton[T any](collection *ServiceCollection, provider func(s *Scope) any) error

AddSingleton registers a service as singleton

func AddTransient

func AddTransient[T any](collection *ServiceCollection, provider func(scope *Scope) any) error

AddTransient registers a service as transient

func GetService

func GetService[T any](s *Scope) (T, error)

GetService is responsible to retrieve or initialize requested service based on it's lifetime.

Types

type Scope

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

Scope is a struct to request services from service collection. Each scope has an isolated object pool for scoped services but will use a shared object pool singleton services. To initialize Scope struct please CreateScope method of ServiceCollection.

type ServiceCollection

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

ServiceCollection is collection of services to use them in your application. This struct contains two pools, first one for registered services and second one for provided singleton services. You may need to initialize ServiceCollection only one time in your application

func InitServiceCollection

func InitServiceCollection() *ServiceCollection

InitServiceCollection initialize a service collection

func (*ServiceCollection) CreateScope

func (collection *ServiceCollection) CreateScope() (*Scope, error)

CreateScope creates a new scope in application to retrieve services

func (*ServiceCollection) Lock

func (collection *ServiceCollection) Lock()

Lock preparing service collection to create scope

type ServiceType

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

ServiceType used to store the configuration of the services in ServiceCollection

Directories

Path Synopsis
examples
fiber Module
gin Module
http Module

Jump to

Keyboard shortcuts

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