import { Entity , EntityConstructor } from "./model/entity" ; import { Injectable } from "@angular/core" ; import { EntityMapperService } from "./entity-mapper.service" ; import { EntitySchemaService } from "./schema/entity-schema.service" ; /**
 * A service that can be used to get the entity-constructors (see  EntityConstructor )
 * from their string-types.
 * This also contains utility methods that deal with creating, loading,
 * checking on the existence and instantiating entities based on the string-types
  @ Injectable ( { providedIn : "root" , } ) export class DynamicEntityService { private static ENTITY_MAP = new Map < string , EntityConstructor < Entity > > ( ) ; /**
     * Registers a new entity so that it can be used using this service.
     * This method should generally never be used other than from the
     *  DatabaseEntity -Decorator
     *
     *  param type param constructor static registerNewEntity ( type , constructor ) { if ( ! ( new constructor ( ) instanceof Entity ) ) { throw Error ( `Tried to register an entity-type that is not a subclass of Entity\n` + `type: ${ type }; constructor: ${ constructor }` ) ; } if ( this . ENTITY_MAP . has ( type ) ) { throw Error ( `Duplicate entity definition: ${ type } is already registered with constructor ${ this . ENTITY_MAP . get ( type ) }` ) ; } this . ENTITY_MAP . set ( type , constructor ) ; } constructor ( private entityMapper , private entitySchemaService ) { } param entityType getEntityConstructor < E extends Entity = any > ( entityType ) { const ctor = DynamicEntityService . ENTITY_MAP . get ( entityType ) ; if ( ! ctor ) { throw new Error ( `Entity-type ${ entityType } does not exist!` ) ; } return ctor as EntityConstructor < E > ; } param entityType param id param initialParameters instantiateEntity < E extends Entity = Entity > ( entityType , id ? , initialParameters ? ) { const ctor = this . getEntityConstructor < E > ( entityType ) ; const entity = id ? new ctor ( id ) : new ctor ( ) ; if ( initialParameters ) { this . entitySchemaService . loadDataIntoEntity ( entity , initialParameters ) ; } return entity ; } /**
     * returns {@code true}, when the entity is registered and could thus be
     * instantiated. Use this method when you don't want to use the throwing
     *  getEntityConstructor or similar throwing methods
     *  param entityType isRegisteredEntity ( entityType ) { return DynamicEntityService . ENTITY_MAP . has ( entityType ) ; } param entityTypes hasAnyRegisteredEntity ( ... entityTypes ) { return entityTypes . some ( ( type ) => this . isRegisteredEntity ( type ) ) ; } /**
     * Load an entity dynamically using the name instead of the constructor
     * like one would in the  EntityMapperService param entityType param entityId async loadEntity < E extends Entity = any > ( entityType , entityId ) { const ctor = this . getEntityConstructor ( entityType ) ; return this . entityMapper . load < E > ( ctor , entityId ) ; } param entityType async loadType < E extends Entity = any > ( entityType ) { const ctor = this . getEntityConstructor ( entityType ) ; return this . entityMapper . loadType < E > ( ctor ) ; } }