ioc

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2024 License: MIT Imports: 4 Imported by: 2

README

Inversion Of Control Container

GoDoc Go Report Card Test

This package provides a simple utility container for faciliting Inversion of Control software pattern. For clarity, this is not a dependency injection framework, merely a go routine safe container to share interfaces across an application.

Tradeoffs

Go has generics, but they aren't as extensive as other programming languages. Because of that, the ioc.Container struct works directly with reflect.Type and reflect.Value. However, there are two access patterns to work with the underlying container with type safety. These are technically optional, but make for a much better developer experience.

Global Access

While it is not ideal to use a global, a global option is provided with static functions for interacting with a singleton ioc.Container (see example).

This package contains no init() functions.

Context Access

Functions to interact with the container from context.Context are provided so that the container can be infered from a parent context. (see example).

Custom Access

A generic container is provided to allow for access to the underlying ioc.Container in a type safe way. You can either use the ioc.GenericContainer directly, or implement the functions from within the generic container in your own custom implementation.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrContainerNotInContext is used when a container is not found in the context.
	ErrContainerNotInContext = errors.New("container not found in context")
)

Functions

func Register

func Register[T any](value T)

Register the supplied value of type T as the default value when using Resolve().

Example
package main

import (
	"fmt"
	"io"
	"os"

	"github.com/renevo/ioc"
)

func main() {
	ioc.Register(5)
	ioc.Register[io.Writer](os.Stdout)

	registered, _ := ioc.Resolve[int]()
	writer, _ := ioc.Resolve[io.Writer]()

	fmt.Fprintln(writer, registered)
}
Output:

5

func RegisterNamed

func RegisterNamed[T any](name string, value T)

RegisterNamed will register the supplied value of type T with the specified name.

func RegisterNamedToContext

func RegisterNamedToContext[T any](ctx context.Context, name string, value T)

RegisterNamedToContext will register the supplied value of type T with the specified name.

This function will panic if the context does not contain a container.

func RegisterToContext

func RegisterToContext[T any](ctx context.Context, value T)

RegisterToContext will register the supplied value of type T as the default value when using ResolveFromContext().

This function will panic if the context does not contain a container.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"os"

	"github.com/renevo/ioc"
)

func main() {
	ctx := ioc.WithContext(context.Background(), &ioc.Container{})

	ioc.RegisterToContext(ctx, 5)
	ioc.RegisterToContext[io.Writer](ctx, os.Stdout)

	registered, _ := ioc.ResolveFromContext[int](ctx)
	writer, _ := ioc.ResolveFromContext[io.Writer](ctx)

	fmt.Fprintln(writer, registered)
}
Output:

5

func Resolve

func Resolve[T any]() (value T, found bool)

Resolve will lookup the default registered value.

func ResolveAll

func ResolveAll[T any]() (values []T)

ResolveAll will lookup and return all values registered.

func ResolveAllFromContext

func ResolveAllFromContext[T any](ctx context.Context) (values []T)

ResolveAllFromContext will lookup and return all values registered.

This function will panic if the context does not contain a container.

func ResolveFromContext

func ResolveFromContext[T any](ctx context.Context) (value T, found bool)

ResolveFromContext will lookup the default registered value.

This function will panic if the context does not contain a container.

func ResolveNamed

func ResolveNamed[T any](name string) (value T, found bool)

ResolveNamed will lookup the value with the specified name.

func ResolveNamedFromContext

func ResolveNamedFromContext[T any](ctx context.Context, name string) (value T, found bool)

ResolveNamedFromContext will lookup the value with the specified name.

This function will panic if the context does not contain a container.

func WithContext

func WithContext(ctx context.Context, container *Container) context.Context

WithContext will place the supplied container into a context.Context. You can then access the container with ioc.FromContext(ctx).

Types

type Container

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

Container registers and resolves types to a map of named values.

func FromContext

func FromContext(ctx context.Context) *Container

FromContext will return a container that is stored in the context. If a container is not found, the global default container will be returned.

func (*Container) Register

func (c *Container) Register(name string, t reflect.Type, value any)

Register will store the supplied type with the value at name.

func (*Container) Resolve

func (c *Container) Resolve(name string, t reflect.Type) (value any, found bool)

Resolve will lookup the type and return a value matching the supplied name.

func (*Container) ResolveAll

func (c *Container) ResolveAll(t reflect.Type) (values []any)

ResolveAll will lookup the type and return all values registered.

type GenericContainer

type GenericContainer[T any] struct {
	Container *Container
}

GenericContainer provices some helper functions to register default values as well as provide the reflection options to work with the underlying ioc.Container.

func (*GenericContainer[T]) Register

func (c *GenericContainer[T]) Register(value T)

Register the supplied value of type T as the default value when using Resolve().

func (*GenericContainer[T]) RegisterNamed

func (c *GenericContainer[T]) RegisterNamed(name string, value T)

RegisterNamed will register the supplied value of type T with the specified name.

func (*GenericContainer[T]) Resolve

func (c *GenericContainer[T]) Resolve() (value T, found bool)

Resolve will lookup the default registered value.

func (*GenericContainer[T]) ResolveAll

func (c *GenericContainer[T]) ResolveAll() (value []T)

ResolveAll will lookup and return all values registered.

func (*GenericContainer[T]) ResolveNamed

func (c *GenericContainer[T]) ResolveNamed(name string) (value T, found bool)

ResolveNamed will lookup the value with the specified name.

Jump to

Keyboard shortcuts

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