Centralize configure-able factory classes

This commit is contained in:
2022-09-26 11:34:23 -05:00
parent 5557aae543
commit c0595f3ef9
23 changed files with 262 additions and 682 deletions

View File

@@ -1,74 +1,23 @@
import {
AbstractFactory,
Container,
DependencyRequirement,
PropertyDependency,
isInstantiable,
DEPENDENCY_KEYS_METADATA_KEY,
Instantiable, FactoryProducer, getPropertyInjectionMetadata,
} from '../../../di'
import {Collection, ErrorWithContext} from '../../../util'
import {Config} from '../../../service/Config'
import {Instantiable, FactoryProducer} from '../../../di'
import {ScopeRepository} from '../types'
import {ConfigScopeRepository} from './ConfigScopeRepository'
import {ConfiguredSingletonFactory} from '../../../di/factory/ConfiguredSingletonFactory'
/**
* A dependency injection factory that matches the abstract ScopeRepository class
* and produces an instance of the configured repository driver implementation.
*/
@FactoryProducer()
export class ScopeRepositoryFactory extends AbstractFactory<ScopeRepository> {
protected get config(): Config {
return Container.getContainer().make<Config>(Config)
export class ScopeRepositoryFactory extends ConfiguredSingletonFactory<ScopeRepository> {
protected getConfigKey(): string {
return 'oauth2.repository.scope'
}
produce(): ScopeRepository {
return new (this.getScopeRepositoryClass())()
protected getDefaultImplementation(): Instantiable<ScopeRepository> {
return ConfigScopeRepository
}
match(something: unknown): boolean {
return something === ScopeRepository
}
getDependencyKeys(): Collection<DependencyRequirement> {
const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getScopeRepositoryClass())
if ( meta ) {
return meta
}
return new Collection<DependencyRequirement>()
}
getInjectedProperties(): Collection<PropertyDependency> {
const meta = new Collection<PropertyDependency>()
let currentToken = this.getScopeRepositoryClass()
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
}
/**
* Return the instantiable class of the configured scope repository backend.
* @protected
* @return Instantiable<ScopeRepository>
*/
protected getScopeRepositoryClass(): Instantiable<ScopeRepository> {
const ScopeRepositoryClass = this.config.get('oauth2.repository.scope', ConfigScopeRepository)
if ( !isInstantiable(ScopeRepositoryClass) || !(ScopeRepositoryClass.prototype instanceof ScopeRepository) ) {
const e = new ErrorWithContext('Provided client repository class does not extend from @extollo/lib.ScopeRepository')
e.context = {
configKey: 'oauth2.repository.client',
class: ScopeRepositoryClass.toString(),
}
}
return ScopeRepositoryClass
protected getAbstractImplementation(): any {
return ScopeRepository
}
}