Documentation
¶
Index ¶
Constants ¶
const ( // ContainerStarting declares container starting event. ContainerStarting = "ContainerStarting" // ContainerStarted declares container started event. ContainerStarted = "ContainerStarted" // ContainerClosing declares container closing event. ContainerClosing = "ContainerClosing" // ContainerClosed declares container closed event. ContainerClosed = "ContainerClosed" // UnhandledPanic declares unhandled panic in container. UnhandledPanic = "UnhandledPanic" )
Events declaration.
Variables ¶
var ErrCircularDependency = errors.New("circular dependency")
ErrCircularDependency declares a cyclic dependency error.
var ErrFactoryReturnedError = errors.New("factory returned error")
ErrFactoryReturnedError declares factory returned error.
var ErrHandlerArgTypeMismatch = errors.New("handler argument type mismatch")
ErrHandlerArgTypeMismatch declares handler argument type mismatch error.
var ErrServiceDuplicated = errors.New("service duplicated")
ErrServiceDuplicated declares service duplicated error.
var ErrServiceNotResolved = errors.New("service not resolved")
ErrServiceNotResolved declares service not resolved error.
var ErrStackLimitReached = errors.New("stack limit reached")
ErrStackLimitReached declares a reach of stack limit error.
Functions ¶
This section is empty.
Types ¶
type Container ¶
type Container interface {
// Start initializes all registered services in dependency order.
// Services are instantiated via their factories.
// Returns an error if initialization fails.
Start() error
// Close shuts down all services in reverse order of their instantiation.
// This method blocks until all services are properly closed.
Close() error
// Done returns a channel that is closed after all services have been shut down.
// Useful for coordinating external shutdown logic.
Done() <-chan struct{}
// Factories returns all registered service factories.
Factories() []*Factory
// Services returns all currently instantiated services.
Services() []any
// Events returns the container-wide event broker instance.
Events() Events
// Resolver returns a service resolver for on-demand dependency injection.
// If the container is not yet started, only requested services and their
// transitive dependencies will be instantiated.
Resolver() Resolver
// Invoker returns a function invoker that can call user-provided functions
// with auto-injected dependencies. Behaves lazily if the container is not started.
Invoker() Invoker
}
Container defines the main interface for a service container.
A Container is responsible for managing the lifecycle of services, including their initialization, shutdown, and dependency resolution.
It supports both eager initialization via Start(), and lazy resolution via Resolver or Invoker before the container is started. Services are created using registered factories, and may optionally implement a Close() method to participate in graceful shutdown.
The container also includes an internal events broker for decoupled communication between services.
type Event ¶
type Event interface {
// Name returns event name.
Name() string
// Args returns event arguments.
Args() []any
}
Event declares service container events.
type Events ¶
type Events interface {
// Subscribe registers an event handler for the specified event name.
//
// The handler must be a function with one of the following signatures:
// - `func(args ...any) [error]`;
// - `func(T1, T2, ...) [error]`.
//
// If the handler returns an error, it will be captured when the event is triggered.
// Panics if the handler is not a function or has an unsupported signature.
Subscribe(name string, handlerFn any)
// Trigger dispatches the given event to all registered handlers.
//
// Handlers are called synchronously in the order they were registered.
// All returned errors are collected and joined into a single error.
Trigger(event Event) error
}
Events defines an interface for a lightweight event broker used for decoupled communication between services within the container.
It supports two types of event handlers:
- handlers with a variadic signature: `func(args ...any) [error]`;
- handlers with a typed signature: `func(T1, T2, ...) [error]`.
Handlers may optionally return an error, which will be collected and joined during the Trigger phase. All handlers for a given event are executed synchronously.
type Factory ¶
type Factory struct {
// contains filtered or unexported fields
}
Factory declares a service factory definition used by the container to construct services.
A Factory wraps a factory function along with its metadata, input/output type information, and internal state used during service resolution and lifecycle management.
It is created using NewFactory or NewService, and typically registered into the container to enable dependency injection and lifecycle control.
func NewFactory ¶
func NewFactory(factoryFn FactoryFunc, opts ...FactoryOpt) *Factory
NewFactory creates a new service factory using the provided factory function.
The factory function must be a valid function. It may accept dependencies as input parameters, and return one or more service instances, optionally followed by an error as the last return value.
Optional configuration can be applied via factory options (`FactoryOpt`), such as providing additional metadata.
The resulting Factory can be registered in the container.
Example:
gontainer.NewFactory(func(db *Database) (*Handler, error), gontainer.WithTag("http"))
func NewService ¶ added in v1.1.0
func NewService[T any](singleton T, opts ...FactoryOpt) *Factory
NewService creates a new service factory that always returns the given singleton value.
This is a convenience helper for registering preconstructed service instances as factories. The returned factory produces the same instance on every invocation.
This is useful for registering constants, mocks, or externally constructed values.
Example:
logger := NewLogger() gontainer.NewService(logger)
func (*Factory) Metadata ¶ added in v1.7.0
func (f *Factory) Metadata() FactoryMetadata
Metadata returns associated factory metadata.
type FactoryFunc ¶ added in v1.7.0
type FactoryFunc any
FactoryFunc declares the type for a service factory function. A factory function may accept dependencies as input parameters and return zero or more service instances, optionally followed by an error. The container validates its signature at runtime using reflection.
Valid example signatures:
// No dependencies, no produced services. func() // No dependencies, one produced service. func() *MyService // One dependency, one produced service, an error. func(db *Database) (*Repo, error) // Multiple dependencies, multiple produced services, an error. func(log *slog.Logger, db *Database) (*Repo1, *Repo2, error) // Multiple dependencies, multiple produced services, no error. func(log *slog.Logger, db *Database) (*Repo1, *Repo2, *Repo3) // One optional dependency, one produced service, an error. func(optionalDB gontainer.Optional[*Database]) (*Repo, error) // One multiple dependency, one produced service, an error. func(multipleDBs gontainer.Multiple[IDatabase]) (*Repo, error)
type FactoryMetadata ¶ added in v1.7.0
FactoryMetadata defines a key-value store for attaching metadata to a factory.
Metadata can be used for annotations, tagging, grouping, versioning, or integration with external tools. It is populated using `WithMetadata()` option.
type FactoryOpt ¶
type FactoryOpt func(*Factory)
FactoryOpt defines a functional option for configuring a service factory.
Factory options allow customizing the behavior or metadata of a factory at the time of its creation, using functions like WithMetadata, WithTag, etc.
func WithMetadata ¶ added in v1.7.0
func WithMetadata(key string, value any) FactoryOpt
WithMetadata adds a custom metadata key-value pair to the factory.
Metadata can be used to attach arbitrary information to a factory, such as labels, tags, annotations, or integration-specific flags. This data is accessible through the factory’s metadata map at runtime.
Example:
gontainer.NewFactory(..., gontainer.WithMetadata("version", "v1.2"))
type InvokeResult ¶ added in v1.9.0
type InvokeResult interface {
// Values returns a slice of function result values.
Values() []any
// Error returns function result error, if any.
Error() error
}
InvokeResult provides access to the invocation result.
type Invoker ¶ added in v1.9.0
type Invoker interface {
// Invoke invokes specified function.
Invoke(fn any) (InvokeResult, error)
}
Invoker defines an interface for invoking functions with automatic dependency resolution.
The Invoke method accepts a function `fn`, resolves its input parameters using the invoker’s dependency resolver, and then calls the function with the resolved arguments.
If the container has not been started yet, dependency resolution happens in lazy mode — only the required arguments and their transitive dependencies are instantiated on demand.
The function may have one of the following return signatures:
- no return values (i.e., `func(...)`),
- a single `error` (i.e., `func(...) error`),
- multiple return values, where the last one may be an `error` (i.e., `func(...) (T1, T2, ..., error)`).
If the last return value implements the `error` interface and is non-nil, it is returned. All other return values are collected into the InvokeResult.
An error is also returned if:
- `fn` is not a function,
- any dependency could not be resolved.
type Multiple ¶ added in v1.12.0
type Multiple[T any] []T
Multiple defines a dependency on zero or more services of the same type.
This generic wrapper is used in service factory function parameters to declare a dependency on all services assignable to type T registered in the container.
The container will collect and inject all matching services into the slice. For interface types, multiple matches are allowed. For concrete (non-interface) types, at most one match is possible.
Example:
func MyFactory(providers gontainer.Multiple[AuthProvider]) {
for _, p := range providers {
...
}
}
type Optional ¶
type Optional[T any] struct { // contains filtered or unexported fields }
Optional defines a dependency on a service that may or may not be registered.
This generic wrapper is used in service factory function parameters to declare that the service of type T is optional. If the container does not contain a matching service, the zero value of T will be injected.
Use the Get() method to access the wrapped value inside the factory.
Example:
func MyFactory(logger gontainer.Optional[Logger]) {
if log := logger.Get(); log != nil {
log.Info("Logger available")
}
}
type Resolver ¶ added in v1.4.0
type Resolver interface {
// Resolve sets the required dependency via the pointer.
Resolve(varPtr any) error
}
Resolver defines an interface for resolving service dependencies.
The Resolve method accepts a pointer to a variable (`varPtr`) and attempts to populate it with an instance of the requested type. The type is determined via reflection based on the element type of `varPtr`.
If the container has not been started yet, Resolve operates in lazy mode — it instantiates only the requested type and its transitive dependencies on demand.
An error is returned if the service of the requested type is not found or cannot be resolved.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
01_basic_usage
module
|
|
|
02_daemon_service
module
|
|
|
03_complete_webapp
module
|
