ts-ioc-container
Version:
Typescript IoC container
69 lines (68 loc) • 2.33 kB
JavaScript
import { isConstructor, pipe } from '../utils';
import { Provider } from '../provider/Provider';
import { DependencyMissingKeyError } from '../errors/DependencyMissingKeyError';
import { getTransformers } from './IRegistration';
import { isProviderPipe } from '../provider/ProviderPipe';
export class Registration {
createProvider;
key;
scopePredicates;
static fromClass(Target) {
const transform = pipe(...getTransformers(Target));
return transform(new Registration(() => Provider.fromClass(Target), Target.name));
}
static fromValue(value) {
if (isConstructor(value)) {
const transform = pipe(...getTransformers(value));
return transform(new Registration(() => Provider.fromValue(value), value.name));
}
return new Registration(() => Provider.fromValue(value));
}
static fromFn(fn) {
return new Registration(() => new Provider(fn));
}
static fromKey(key) {
return new Registration(() => Provider.fromKey(key));
}
mappers = [];
aliases = new Set();
constructor(createProvider, key, scopePredicates = []) {
this.createProvider = createProvider;
this.key = key;
this.scopePredicates = scopePredicates;
}
bindToKey(key) {
this.key = key;
return this;
}
bindToAlias(alias) {
this.aliases.add(alias);
return this;
}
pipe(...mappers) {
const fns = mappers.map((m) => (isProviderPipe(m) ? m.mapProvider.bind(m) : m));
this.mappers.push(...fns);
return this;
}
when(...predicates) {
this.scopePredicates.push(...predicates);
return this;
}
matchScope(container) {
if (this.scopePredicates.length === 0) {
return true;
}
const [first, ...rest] = this.scopePredicates;
return rest.reduce((prev, curr) => curr(container, prev), first(container));
}
applyTo(container) {
if (!this.matchScope(container)) {
return;
}
if (!this.key) {
throw new DependencyMissingKeyError('No key provided for registration');
}
const provider = this.createProvider();
container.register(this.key, provider.pipe(...this.mappers), { aliases: [...this.aliases] });
}
}