Centralize configure-able factory classes
This commit is contained in:
@@ -1,79 +1,23 @@
|
||||
import {
|
||||
AbstractFactory,
|
||||
Container,
|
||||
DependencyRequirement,
|
||||
PropertyDependency,
|
||||
isInstantiable,
|
||||
DEPENDENCY_KEYS_METADATA_KEY,
|
||||
StaticClass, Instantiable, getPropertyInjectionMetadata,
|
||||
} from '../di'
|
||||
import {Collection, ErrorWithContext} from '../util'
|
||||
import {Logging} from '../service/Logging'
|
||||
import {Config} from '../service/Config'
|
||||
import {Instantiable, FactoryProducer} from '../di'
|
||||
import {ViewEngine} from './ViewEngine'
|
||||
import {PugViewEngine} from './PugViewEngine'
|
||||
import {ConfiguredSingletonFactory} from '../di/factory/ConfiguredSingletonFactory'
|
||||
|
||||
/**
|
||||
* Dependency factory whose token matches the abstract ViewEngine class, but produces
|
||||
* a particular ViewEngine implementation based on the configuration.
|
||||
*/
|
||||
export class ViewEngineFactory extends AbstractFactory<ViewEngine> {
|
||||
protected readonly logging: Logging
|
||||
|
||||
protected readonly config: Config
|
||||
|
||||
constructor() {
|
||||
super({})
|
||||
this.logging = Container.getContainer().make<Logging>(Logging)
|
||||
this.config = Container.getContainer().make<Config>(Config)
|
||||
@FactoryProducer()
|
||||
export class ViewEngineFactory extends ConfiguredSingletonFactory<ViewEngine> {
|
||||
protected getConfigKey(): string {
|
||||
return 'server.view_engine.driver'
|
||||
}
|
||||
|
||||
produce(): ViewEngine {
|
||||
return new (this.getViewEngineClass())()
|
||||
protected getDefaultImplementation(): Instantiable<ViewEngine> {
|
||||
return PugViewEngine
|
||||
}
|
||||
|
||||
match(something: unknown): boolean {
|
||||
return something === ViewEngine
|
||||
}
|
||||
|
||||
getDependencyKeys(): Collection<DependencyRequirement> {
|
||||
const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getViewEngineClass())
|
||||
if ( meta ) {
|
||||
return meta
|
||||
}
|
||||
return new Collection<DependencyRequirement>()
|
||||
}
|
||||
|
||||
getInjectedProperties(): Collection<PropertyDependency> {
|
||||
const meta = new Collection<PropertyDependency>()
|
||||
let currentToken = this.getViewEngineClass()
|
||||
|
||||
do {
|
||||
const loadedMeta = getPropertyInjectionMetadata(currentToken)
|
||||
if ( loadedMeta ) {
|
||||
meta.concat(loadedMeta)
|
||||
}
|
||||
currentToken = Object.getPrototypeOf(currentToken)
|
||||
} while (Object.getPrototypeOf(currentToken) !== Function.prototype && Object.getPrototypeOf(currentToken) !== Object.prototype)
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the config, get the implementation of the ViewEngine that should be used in the application.
|
||||
* @protected
|
||||
*/
|
||||
protected getViewEngineClass(): StaticClass<ViewEngine, Instantiable<ViewEngine>> {
|
||||
const ViewEngineClass = this.config.get('server.view_engine.driver', PugViewEngine)
|
||||
|
||||
if ( !isInstantiable(ViewEngineClass) || !(ViewEngineClass.prototype instanceof ViewEngine) ) {
|
||||
const e = new ErrorWithContext('Provided session class does not extend from @extollo/lib.ViewEngine')
|
||||
e.context = {
|
||||
configKey: 'server.view_engine.driver',
|
||||
class: ViewEngineClass.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
return ViewEngineClass
|
||||
protected getAbstractImplementation(): any {
|
||||
return ViewEngine
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user