di_plus

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2022 License: MIT Imports: 2 Imported by: 0

README

Go

Dependency Injection

This package contains all of the fundamental functionalities for dependency injection (DI). A ServiceProvider can be used to register services and consume them in your application.

Features

This package provides the following features:

  • Register services with a single instance (singleton only) or with a function (factory);
  • Use of generic function to get your desired service;
  • Three service lifetimes: singleton, scoped, transient;
  • Async initialization (coming soon)

Service Lifetimes

A service can have the following lifetimes:

  • Transient - a new instance is created every time it is requested
  • Singleton - a single, new instance is created the first time it is requested
  • Scoped - a new instance is created once per ServiceScope the first time it is requested

Scope Scenarios

There scenarios where a service needs to be scoped; for example, for the lifetime of a HTTP request. A service definitely shouldn't live for the life of the application (e.g. singleton), but it also shouldn't be created each time it's requested within the request (e.g. transient). A scoped service lives for the lifetime of the container (ServiceScope) it was created from.

Installation

go get github.com/fairking/di_plus

Usage

package main

import (
    "github.com/fairking/di_plus"
)

type MySettingsService struct {
	Connection string
}

type MyDatabaseService struct {
	Settings MyDatabaseService
}

// Register Services
services := NewServiceBuilder().
    // Singleton
    Register(
        GetTypeOf[MySettingsService](),
        ServiceTypeEnum.Singleton,
        func(s IServiceProvider) (interface{}, error) {
            return MySettingsService{Connection: "server=127.0.0.1;uid=root;pwd=12345;database=test"}, nil
        },
    ).
    // Scoped
    Register(
        GetTypeOf[MyDatabaseService](),
        ServiceTypeEnum.Scoped,
        func(s IServiceProvider) (interface{}, error) {
            return MyDatabaseService{Settings: GetService[*MySettingsService](s)}, nil
        },
    ).
    Build()

// Get Singleton
settings := services.GetService("MySettingsService").(*MySettingsService) // Creates a new settings value
// or
settings2 := GetService[*MySettingsService](services) // Returns the existing settings value
// settings and settings2 pointing to the same value

// Get Scope
{
    scope := services.GetScope()
    db := GetService[*MyDatabaseService](scope) // Creates a new database service value
    // or
    db_, err := GetServiceOr[*MyDatabaseService](scope) // Returns the existing database service value

    settings3 := GetService[*MySettingsService](services) // Returns the existing settings value
}

// Get Scope
{
    scope := services.GetScope()
    db2 := GetService[*MyDatabaseService](scope) // Creates a new database service value
    // or
    db2_, err := GetServiceOr[*MyDatabaseService](scope) // Returns the existing database service value

    settings3 := GetService[*MySettingsService](services) // Returns the existing settings value
}

// db and db_ is the same value, but db and db2 are different

Contribution

If you have questions please create a new issue.

Donations

Donate with Ӿ nano crypto (XNO).

di_plus Donations

Thank you!

Documentation

Overview

Service Provider Interface used for dependency injection IOC.

Service Descriptor used for dependency injection IOC.

Service Provider used for dependency injection IOC.

Service Scope used for dependency injection IOC.

Service Type Enum used for dependency injection IOC.

Index

Constants

This section is empty.

Variables

View Source
var ServiceTypeEnum = &ServiceTypeStruct{
	Singleton: 0,
	Scoped:    1,
	Transient: 2,
}

Functions

func GetService

func GetService[T interface{}](s IServiceProvider) T

Gets an instance of the given service or panics. Panics if the given service not found (has not been registered). Returns an error if the given service is scoped (not allowed in root). Returns an error if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service := GetService[*MyService](service_provider_or_scope)`.

func GetServiceOr

func GetServiceOr[T interface{}](s IServiceProvider) (T, error)

Gets an instance of the given service or error. Returns an error if the given service not found (has not been registered). Returns an error if the given service is scoped (not allowed in root). Returns an error if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service, err := GetServiceOr[*MyService](service_provider_or_scope)`.

func GetTypeOf

func GetTypeOf[T any]() reflect.Type

Returns a type of the given T.

func Register

func Register[T interface{}](s ServiceProvider, serv_type ServiceType, factory func(IServiceProvider) (T, error))

Registers a new service with a factory constructor. Eg. Register[MyService](service_provider, ServiceTypeEnum.Singleton, func(s IServiceProvider) (MyService, error) { return &MyService{}, nil } ).

func RegisterInst

func RegisterInst[T interface{}](s ServiceProvider, instance T)

Registers a new service with an instance. Only applicable for singleton services. Eg. `Register[MyService](service_provider, &MyService{})`.

Types

type IServiceProvider

type IServiceProvider interface {
	// Gets an instance of the given service or panics
	GetService(string) interface{}
	// Gets an instance of the given service or error
	GetServiceOr(string) (interface{}, error)
}

type ServiceDescriptor

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

type ServiceProvider

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

func NewServiceProvider

func NewServiceProvider() ServiceProvider

Creates a new instance of service provider.

func (ServiceProvider) Build

func (p ServiceProvider) Build() *ServiceProvider

Builds a service provider, or just simply returns a reference.

func (ServiceProvider) CreateScope

func (s ServiceProvider) CreateScope() *ServiceScope

Creates a service scope.

func (ServiceProvider) GetService

func (s ServiceProvider) GetService(service_name string) interface{}

Gets an instance of the given service or panics. Panics if the given service not found (has not been registered). Panics if the given service is scoped (not allowed in root). Panics if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service := service_provider.GetService("MyService").(*MyService)`.

func (ServiceProvider) GetServiceOr

func (s ServiceProvider) GetServiceOr(service_name string) (interface{}, error)

Gets an instance of the given service or error. Returns an error if the given service not found (has not been registered). Returns an error if the given service is scoped (not allowed in root). Returns an error if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service, err := service_provider.GetServiceOr("MyService").(*MyService)`.

func (ServiceProvider) Register

func (p ServiceProvider) Register(inst_type reflect.Type, serv_type ServiceType, factory func(IServiceProvider) (interface{}, error)) ServiceProvider

Registers a new service with a factory constructor. Eg. `service_provider.Register(GetTypeOf(MyService), ServiceTypeEnum.Singleton, func(s IServiceProvider) (interface{}, error) { return &MyService{}, nil } )`.

func (ServiceProvider) RegisterInst

func (p ServiceProvider) RegisterInst(inst_type reflect.Type, instance interface{}) ServiceProvider

Registers a new service with an instance. Only applicable for singleton services. Eg. `service_provider.RegisterInst(GetTypeOf(MyService), &MyService{})`.

type ServiceScope

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

func (ServiceScope) GetService

func (s ServiceScope) GetService(service_name string) interface{}

Gets an instance of the given service or panics. Panics if the given service not found (has not been registered). Panics if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service := service_scope.GetService("MyObj").(MyObj)`.

func (ServiceScope) GetServiceOr

func (s ServiceScope) GetServiceOr(service_name string) (interface{}, error)

Gets an instance of the given service or error. Returns an error if the given service not found (has not been registered). Returns an error if the given service is scoped (not allowed in root). Returns an error if the given service is not transient and not a pointer (the factory must produce a reference: &MyService{}). Eg. `my_service, err := service_scope.GetServiceOr("MyObj").(MyObj)`.

type ServiceType

type ServiceType = uint8

type ServiceTypeStruct

type ServiceTypeStruct struct {
	// Every subsequent request of the singleton service implementation from the service container uses the same instance.
	Singleton ServiceType
	// Scoped lifetime indicates that services are created once per ServiceScope. Do not resolve scoped services from ServiceProvider but rather from ServiceScope.
	Scoped ServiceType
	// Transient lifetime services are created each time they're requested from the service container
	Transient ServiceType
}

Service Type Enum.

Jump to

Keyboard shortcuts

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