Begin abstracting global container into injector
This commit is contained in:
parent
f00233d49a
commit
9796a7277e
@ -7,6 +7,7 @@ import {ClosureFactory} from './factory/ClosureFactory'
|
|||||||
import NamedFactory from './factory/NamedFactory'
|
import NamedFactory from './factory/NamedFactory'
|
||||||
import SingletonFactory from './factory/SingletonFactory'
|
import SingletonFactory from './factory/SingletonFactory'
|
||||||
import {InvalidDependencyKeyError} from './error/InvalidDependencyKeyError'
|
import {InvalidDependencyKeyError} from './error/InvalidDependencyKeyError'
|
||||||
|
import {ContainerBlueprint} from './ContainerBlueprint'
|
||||||
|
|
||||||
export type MaybeFactory<T> = AbstractFactory<T> | undefined
|
export type MaybeFactory<T> = AbstractFactory<T> | undefined
|
||||||
export type MaybeDependency = any | undefined
|
export type MaybeDependency = any | undefined
|
||||||
@ -23,6 +24,11 @@ export class Container {
|
|||||||
const existing = <Container | undefined> globalRegistry.getGlobal('extollo/injector')
|
const existing = <Container | undefined> globalRegistry.getGlobal('extollo/injector')
|
||||||
if ( !existing ) {
|
if ( !existing ) {
|
||||||
const container = new Container()
|
const container = new Container()
|
||||||
|
|
||||||
|
ContainerBlueprint.getContainerBlueprint()
|
||||||
|
.resolve()
|
||||||
|
.map(factory => container.registerFactory(factory))
|
||||||
|
|
||||||
globalRegistry.setGlobal('extollo/injector', container)
|
globalRegistry.setGlobal('extollo/injector', container)
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
42
src/di/ContainerBlueprint.ts
Normal file
42
src/di/ContainerBlueprint.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import {Instantiable} from './types'
|
||||||
|
import NamedFactory from './factory/NamedFactory'
|
||||||
|
import {AbstractFactory} from './factory/AbstractFactory'
|
||||||
|
import {Factory} from './factory/Factory'
|
||||||
|
|
||||||
|
export class ContainerBlueprint {
|
||||||
|
private static instance?: ContainerBlueprint
|
||||||
|
|
||||||
|
public static getContainerBlueprint(): ContainerBlueprint {
|
||||||
|
if ( !this.instance ) {
|
||||||
|
this.instance = new ContainerBlueprint()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.instance
|
||||||
|
}
|
||||||
|
|
||||||
|
protected factories: (() => AbstractFactory<any>)[] = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a basic instantiable class as a standard Factory with this container,
|
||||||
|
* identified by a string name rather than static class.
|
||||||
|
* @param {string} name - unique name to identify the factory in the container
|
||||||
|
* @param {Instantiable} dependency
|
||||||
|
*/
|
||||||
|
registerNamed(name: string, dependency: Instantiable<any>): this {
|
||||||
|
this.factories.push(() => new NamedFactory(name, dependency))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a basic instantiable class as a standard Factory with this container.
|
||||||
|
* @param {Instantiable} dependency
|
||||||
|
*/
|
||||||
|
register(dependency: Instantiable<any>): this {
|
||||||
|
this.factories.push(() => new Factory(dependency))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(): AbstractFactory<any>[] {
|
||||||
|
return this.factories.map(x => x())
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ import {
|
|||||||
DEPENDENCY_KEYS_SERVICE_TYPE_KEY,
|
DEPENDENCY_KEYS_SERVICE_TYPE_KEY,
|
||||||
PropertyDependency,
|
PropertyDependency,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import {Container} from '../Container'
|
import {ContainerBlueprint} from '../ContainerBlueprint'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a collection of dependency requirements for the given target object.
|
* Get a collection of dependency requirements for the given target object.
|
||||||
@ -145,9 +145,9 @@ export const Singleton = (name?: string): ClassDecorator => {
|
|||||||
Injectable()(target)
|
Injectable()(target)
|
||||||
|
|
||||||
if ( name ) {
|
if ( name ) {
|
||||||
Container.getContainer().registerNamed(name, target)
|
ContainerBlueprint.getContainerBlueprint().registerNamed(name, target)
|
||||||
} else {
|
} else {
|
||||||
Container.getContainer().register(target)
|
ContainerBlueprint.getContainerBlueprint().register(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ export * from './factory/Factory'
|
|||||||
export * from './factory/NamedFactory'
|
export * from './factory/NamedFactory'
|
||||||
export * from './factory/SingletonFactory'
|
export * from './factory/SingletonFactory'
|
||||||
|
|
||||||
|
export * from './ContainerBlueprint'
|
||||||
export * from './Container'
|
export * from './Container'
|
||||||
export * from './ScopedContainer'
|
export * from './ScopedContainer'
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Application} from './Application'
|
import {Application} from './Application'
|
||||||
import {Container, DependencyKey} from '../di'
|
import {Container, DependencyKey, Injectable} from '../di'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base type for a class that supports binding methods by string.
|
* Base type for a class that supports binding methods by string.
|
||||||
@ -25,12 +25,11 @@ export function isBindable(what: unknown): what is Bindable {
|
|||||||
/**
|
/**
|
||||||
* Base for classes that gives access to the global application and container.
|
* Base for classes that gives access to the global application and container.
|
||||||
*/
|
*/
|
||||||
|
@Injectable()
|
||||||
export class AppClass {
|
export class AppClass {
|
||||||
/** The global application instance. */
|
/** The global application instance. */
|
||||||
private readonly appClassApplication!: Application;
|
private get appClassApplication(): Application {
|
||||||
|
return Application.getApplication()
|
||||||
constructor() {
|
|
||||||
this.appClassApplication = Application.getApplication()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the global Application. */
|
/** Get the global Application. */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Container} from '../di'
|
import {Container, ContainerBlueprint} from '../di'
|
||||||
import {
|
import {
|
||||||
ErrorWithContext,
|
ErrorWithContext,
|
||||||
globalRegistry,
|
globalRegistry,
|
||||||
@ -52,6 +52,11 @@ export class Application extends Container {
|
|||||||
const existing = <Container | undefined> globalRegistry.getGlobal('extollo/injector')
|
const existing = <Container | undefined> globalRegistry.getGlobal('extollo/injector')
|
||||||
if ( !existing ) {
|
if ( !existing ) {
|
||||||
const container = new Application()
|
const container = new Application()
|
||||||
|
|
||||||
|
ContainerBlueprint.getContainerBlueprint()
|
||||||
|
.resolve()
|
||||||
|
.map(factory => container.registerFactory(factory))
|
||||||
|
|
||||||
globalRegistry.setGlobal('extollo/injector', container)
|
globalRegistry.setGlobal('extollo/injector', container)
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
@ -74,6 +79,11 @@ export class Application extends Container {
|
|||||||
return app
|
return app
|
||||||
} else {
|
} else {
|
||||||
const app = new Application()
|
const app = new Application()
|
||||||
|
|
||||||
|
ContainerBlueprint.getContainerBlueprint()
|
||||||
|
.resolve()
|
||||||
|
.map(factory => app.registerFactory(factory))
|
||||||
|
|
||||||
globalRegistry.setGlobal('extollo/injector', app)
|
globalRegistry.setGlobal('extollo/injector', app)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user