You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lib/src/di/ScopedContainer.ts

62 lines
1.9 KiB

import {Container, MaybeDependency, MaybeFactory} from "./Container"
import {DependencyKey} from "./types"
/**
* A container that uses some parent container as a base, but
* can have other factories distinct from that parent.
*
* If an instance is not found in this container, it will be resolved from
* the parent container.
*
* However, if an instance IS found in this container, it will ALWAYS be
* resolved from this container, rather than the parent.
*
* This can be used to create scope-specific containers that can still resolve
* the global dependencies, while keeping scope-specific dependencies separate.
*
* @example
* The Request class from @extollo/lib is a ScopedContainer. It can resolve
* all dependencies that exist in the global Container, but it can also have
* request-specific services (like the Session) injected into it.
*
* @extends Container
*/
export class ScopedContainer extends Container {
/**
* Create a new scoped container based on a parent container instance.
* @param container
*/
public static fromParent(container: Container) {
return new ScopedContainer(container);
}
constructor(
private parentContainer: Container,
) {
super()
this.registerSingletonInstance<ScopedContainer>(ScopedContainer, this)
}
hasInstance(key: DependencyKey): boolean {
return super.hasInstance(key) || this.parentContainer.hasInstance(key)
}
hasKey(key: DependencyKey): boolean {
return super.hasKey(key) || this.parentContainer.hasKey(key)
}
getExistingInstance(key: DependencyKey): MaybeDependency {
const inst = super.getExistingInstance(key)
if ( inst ) return inst;
return this.parentContainer.getExistingInstance(key);
}
resolve(key: DependencyKey): MaybeFactory {
const factory = super.resolve(key);
if ( factory ) return factory;
return this.parentContainer?.resolve(key);
}
}