rsdi
Version:
TypeScript dependency injection container. Strong types without decorators.
67 lines (66 loc) • 3.12 kB
TypeScript
import { type DenyInputKeys, type Factory, type IDIContainer, type ResolvedDependencies, type StringLiteral } from './types.js';
/**
* Dependency injection container
*/
export declare class DIContainer<ContainerResolvers extends ResolvedDependencies = {}> {
private context;
private resolvedDependencies;
private resolvers;
/**
* Adds new dependency resolver to the container. If dependency with given name already exists it will throw an error.
* Use update method instead. It will override existing dependency.
* @param name
* @param resolver
*/
add<N extends string, R extends Factory<ContainerResolvers>>(name: StringLiteral<DenyInputKeys<N, keyof ContainerResolvers>>, resolver: R): IDIContainer<ContainerResolvers & {
[n in N]: ReturnType<R>;
}>;
/**
* Extends container with given function. It will pass container as an argument to the function.
* Function should return new container with extended resolvers.
* It is useful when you want to split your container into multiple files.
* You can create a file with resolvers and extend container with it.
* You can also use it to create multiple containers with different resolvers.
*
* For example:
*
* const container = new DIContainer()
* .extend(addValidators)
*
* export type DIWithValidators = ReturnType<typeof addValidators>;
* export const addValidators = (container: DIWithDataAccessors) => {
* return container
* .add('myValidatorA', ({ a, b, c }) => new MyValidatorA(a, b, c))
* .add('myValidatorB', ({ a, b, c }) => new MyValidatorB(a, b, c));
* };
* @param diConfigurationFactory
*/
extend<Extension extends ResolvedDependencies, FactoryFunction extends (container: IDIContainer<ContainerResolvers>) => IDIContainer<ContainerResolvers & Extension>>(diConfigurationFactory: FactoryFunction): IDIContainer<ContainerResolvers & Extension>;
/**
* Resolve dependency by name. Alternatively you can use property access to resolve dependency.
* For example: const { a, b } = container;
* @param dependencyName
*/
get<Name extends keyof ContainerResolvers>(dependencyName: Name): ContainerResolvers[Name];
/**
* Checks if dependency with given name exists
* @param name
*/
has(name: string): boolean;
/**
* Updates existing dependency resolver. If dependency with given name does not exist it will throw an error.
* In most cases you don't need to override dependencies and should use add method instead. This approach will
* help you to avoid overriding dependencies by mistake.
*
* You may want to override dependency if you want to mock it in tests.
* @param name
* @param resolver
*/
update<N extends keyof ContainerResolvers, R extends Factory<ContainerResolvers>>(name: StringLiteral<N>, resolver: R): IDIContainer<{
[n in N]: ReturnType<R>;
} & {
[P in Exclude<keyof ContainerResolvers, N>]: ContainerResolvers[P];
}>;
private setValue;
private toContainer;
}