Services
Dependency Injection & Lifecycle Management.
Daydreams utilizes a Dependency Injection (DI) container and a Service Provider pattern to manage dependencies and component lifecycles effectively.
Dependency Injection (container.ts
)
At the heart of the framework's modularity is a simple Dependency Injection
container, created using createContainer()
. The container is responsible for
instantiating and providing access to various services and components throughout
the agent's lifecycle.
Purpose:
- Decouples components by removing the need for them to know how to create their dependencies.
- Manages the lifecycle of services (e.g., ensuring only one instance of a database client exists).
- Makes components like loggers, clients, or configuration easily accessible.
Core Methods:
container.register(token, factory)
: Registers a factory function. A new instance is created every timeresolve
is called for thetoken
.container.singleton(token, factory)
: Registers a factory function, but the instance is created only once on the firstresolve
call. Subsequent calls return the same instance.container.instance(token, value)
: Registers a pre-existing object instance directly.container.resolve<Type>(token)
: Retrieves the instance associated with thetoken
. Throws an error if the token is not registered.container.alias(aliasToken, originalToken)
: Creates an alternative name (aliasToken
) to resolve an existingoriginalToken
.
The main Agent
instance, Logger
, TaskRunner
, and other core components are
typically registered within the container when createDreams
is called.
Service Providers (serviceProvider.ts
)
While you could register everything directly with the container, Daydreams uses a Service Provider pattern to organize the registration and initialization (booting) of related services, especially within extensions.
Purpose:
- Groups related service registrations.
- Provides a dedicated
boot
phase for initialization logic that might depend on other services already being registered (e.g., connecting a client after its configuration is registered).
Defining a Service Provider:
Use the service
helper function:
Lifecycle:
- Registration: When a service provider is added to the agent (usually via
an extension), its
register
method is called immediately by theServiceManager
(created internally increateDreams
). - Booting: When
agent.start()
is called, theServiceManager
iterates through all registered service providers and calls theirboot
methods after allregister
methods have completed.
Services and the DI container form the backbone for managing dependencies and initializing components within Daydreams agents and extensions.