Appends a new service instance to an existing array within the container using an InjectableFunction
.
An injectable function that returns the Service.
The updated Container, now including the new service instance appended to the array specified by the token.
// Assume there's a container with an array ready to hold service instances
const container = Container.fromObject({ services: [] as Service[] });
// Append a new Service instance to the 'services' array using a factory function
const newContainer = container.append(Injectable('services', () => new Service()));
// Retrieve the services array to see the added Service instance
console.log(newContainer.get('services').length); // prints 1;
Appends an injectable class factory to the array associated with a specified token in the current Container, then returns the new Container with the updated value. This method is applicable under the following conditions:
const container = Container.fromObject({ services: [] as Service[] });
const newContainer = container.appendClass('services', Service);
console.log(newContainer.get('services').length); // prints 1;
@param token - A unique Token which will correspond to the previously defined typed array.
@param cls - A class with a constructor that takes dependencies as arguments, which returns the Service.
@returns The updated Container with the new service instance appended to the specified array
Appends a value to the array associated with a specified token in the current Container, then returns the new Container with the updated value. This method is applicable under the following conditions:
const container = Container.fromObject({ services: [1, 2, 3] as number[] });
const newContainer = container.appendValue('services', 4);
console.log(newContainer.get('services')); // prints [1, 2, 3, 4];
The updated Container with the appended value in the specified array.
Creates a copy of this Container, optionally scoping specified services to the new copy. Unspecified services are shared between the original and copied containers, while factory functions for scoped services are re-invoked upon service resolution in the new container.
This can be useful, for example, if different parts of an application wish to use the same Service interface, but do not want to share a reference to same Service instance.
Consider an example where we have a UserListService
that manages a list of users.
If our application needs to display two user lists that can be edited independently
(e.g., in separate components or pages), it would be beneficial to create a distinct Container
for each list component. By scoping the UserListService
to each Container,
we ensure that each component receives its own independent copy of the service.
This setup allows for independent edits to each user list without any overlap or
interference between the two components.
Optional
scopedServices: TokensAn optional list of tokens for Services to be scoped to the new Container copy. Services not specified will be shared with the original Container, while specified ones will be re-instantiated in the new Container.
A new Container copy that shares the original's services, with specified services scoped as unique instances to the new Container.
// Create the original container and provide the UserListService
const originalContainer = Container.provides(Injectable('UserListService', () => new UserListService()));
// Create a new Container copy with UserListService scoped, allowing for independent user lists
const newListContainer = originalContainer.copy(['UserListService']);
// Each Container now manages its own independent UserListService service instance
Retrieves a reference to this Container.
The CONTAINER token.
This Container.
Retrieves a Service from the Container by its token. On first request, the service's factory function is invoked and the result is memoized for future requests, ensuring singleton behavior.
A unique token corresponding to a Service
A Service corresponding to the given Token.
Merges additional services from a given PartialContainer
into this container,
creating a new Container
instance. Services defined in the PartialContainer
take precedence
in the event of token conflicts, meaning any service in the PartialContainer
with the same token
as one in this container will override the existing service.
If the same PartialContainer
is provided to multiple containers, each resulting container will have its own
independent instance of the services defined in the PartialContainer
, ensuring no shared state between them.
The PartialContainer
that provides the additional services to be merged into this container.
This container defines services and their dependencies that are to be integrated.
A new Container
instance that combines the services of this container with those from the provided
PartialContainer
, with services from the PartialContainer
taking precedence in case of conflicts.
Merges services from another Container
into this container, creating a new Container
instance.
Services from the provided Container
take precedence in the event of token conflicts.
Importantly, services from the provided Container
are shared between the original (source) container
and the new (destination) container created by this method. This means that both containers will reference
the same service instances, ensuring consistency but not isolation.
If isolation is required (i.e., separate instances of the services in different containers), the source container should be copied before being passed to this method. This ensures that new instances of the services are created in the new container, avoiding shared state issues.
The Container
that provides the additional services to be merged.
A new Container
instance that combines services from this container with those from the
provided container, with services from the provided container taking precedence in case of conflicts.
Registers a new service in this Container using an InjectableFunction
. This function defines how the service
is created, including its dependencies and the token under which it will be registered. When called, this method
adds the service to the container, ready to be retrieved via its token.
The InjectableFunction
must specify:
Token
identifying the service.Tokens
representing the dependencies needed to create the service.This method ensures type safety by verifying that all required dependencies are available in the container and match the expected types. If a dependency is missing or a type mismatch occurs, a compiler error is raised, preventing runtime errors and ensuring reliable service creation.
The InjectableFunction
that constructs the service. It should take required dependencies as arguments
and return the newly created service.
A new Container
instance containing the added service, allowing chaining of multiple provides
calls.
Registers a service in the container using a class constructor, simplifying the service creation process.
This method is particularly useful when the service creation logic can be encapsulated within a class constructor.
A unique Token used to identify and retrieve the service from the container.
A class with a constructor that takes dependencies as arguments and a static dependencies
field
specifying these dependencies.
A new Container instance containing the newly created service, allowing for method chaining.
Registers a static value as a service in the container. This method is ideal for services that do not require dynamic instantiation and can be provided directly as they are.
A new Container instance that includes the provided service, allowing for chaining additional
provides
calls.
Runs the factory functions for all services listed in the provided PartialContainer, along with their dependencies that are registered within this container.
This method is particularly useful for preemptively initializing services that require setup before use. It ensures that services are ready when needed without waiting for a lazy instantiation.
Note: This method does not add new services to the container.
The PartialContainer specifying which services to initialize.
The current container unchanged, with dependencies of the services listed in the provided PartialContainer initialized as needed.
// Create initializers for caching and reporting setup that depend on a request service
const initializers = new PartialContainer({})
.provides(Injectable("initCache", ["request"], (request: Request) => fetchAndPopulateCache(request)))
.provides(Injectable("setupReporter", ["request"], (request: Request) => setupReporter(request)));
// Setup the main container with a request service and run the initializers
const container = Container
.provides(Injectable("request", () => (url: string) => fetch(url)))
.run(initializers);
// At this point, `initCache` and `setupReporter` have been executed using the `request` service.
// And the `request` service itself has also been initialized within the `container`.
Runs the factory function for a specified service provided by InjectableFunction, along with its dependencies that are registered within this container.
This method is particularly useful for services that need to be set up before they are used. It ensures that the service is ready when needed, without relying on lazy instantiation.
Note: This method does not add new services to the container.
The InjectableFunction specifying the service to initialize.
The current container unchanged, with dependencies of the provided InjectableFunction initialized as needed.
// Setup a container with a request service and directly run the `initCache` service
const container = Container
.provides(Injectable("request", () => (url: string) => fetch(url)))
.run(Injectable("initCache", ["request"], (request: Request) => fetchAndPopulateCache(request)));
// At this point, `initCache` has been executed using the `request` service.
// And the `request` service itself has also been initialized.
Static
fromCreates a new Container from a plain object containing service definitions. Each property of the object is treated as a unique token, and its corresponding value is registered in the Container as a service under that token. This method offers a convenient way to quickly bootstrap a container with predefined services.
A plain object where each property (token) maps to a service value. This object defines the initial set of services to be contained within the new Container instance.
A new Container instance populated with the provided services.
// Creating a container with simple value services
const container = Container.fromObject({ foo: 1, bar: 'baz' });
// Retrieving services from the container
console.log(container.get('foo')); // prints 1
console.log(container.get('bar')); // prints 'baz'
In this example, container
is of type Container<{ foo: number, bar: string }>
indicating
that it holds services under the tokens 'foo' and 'bar' with corresponding types.
Static
providesCreates a new [Container] by providing a [PartialContainer] that has no dependencies.
Creates a new [Container] by providing a Service that has no dependencies.
Static
providesRegisters a static value as a service in a new Container. Ideal for services that don't require instantiation or dependencies.
NOTE: This method acts as a syntactic shortcut, essentially registering a factory function that directly returns the provided value.
A new Container instance with the specified service registered.
Represents the dependency injection container that manages the registration, creation, and retrieval of services. The Container class is central to the dependency injection process, facilitating typesafe injection and retrieval of services based on tokens.
Example