2

У меня есть приложение TypeScript, и я использую Inversify для IoC.Как ввести асинхронную зависимость в inversify?

У меня есть класс соединений:

'use strict'; 
import { injectable } from 'inversify'; 
import { createConnection, Connection } from "typeorm"; 
import { Photo, PhotoMetadata, Author, Album } from '../index'; 

@injectable() 
class DBConnectionManager { 

    public createPGConnection(): Promise<Connection> { 
     return createConnection({ 
      driver: { 
       type: "postgres", 
       host: "host", 
       port: 5432, 
       username: "username", 
       password: "password", 
       database: "username" 
      }, 
      entities: [ 
       Photo, PhotoMetadata, Author, Album 
      ], 
      autoSchemaSync: true, 
     }); 

    } 

} 

export { DBConnectionManager }; 

После того как я создал свою связь, я хочу, чтобы связать соединение в моем контейнере:

kernel.bind<Connection>('DefaultConnection').toConstantValue(getConnectionManager().get()); 

, а затем я хочу, чтобы ввести его в другой класс:

import { injectable, inject } from 'inversify'; 
import { Connection, FindOptions } from "typeorm"; 
import { IGenericRepository, ObjectType } from '../index'; 


    @injectable() 
    class GenericRepository<T> implements IGenericRepository<T> { 

     private connection: Connection; 
     private type: ObjectType<T>; 

     constructor(@inject('DefaultConnection') connection: Connection) { 
      this.connection = connection; 
     } 

Так что, в моей конфигурации контейнера, как я могу привязать DefaultConnection, которому нужно подождать для CreateConnection я могу сделать с асинхронным и ждать, но я интересно, если есть способ очистки для того чтобы достигнуть этого в inversify

ответ

4

Inversify 2.0 включает поддержку асинхронных заводов (Поставщики AKA)

Поставщик позволяет может объявить провайдера следующим образом:

container.bind<<DbClient>("DbClient").to(DbClientClass); 

container.bind<interfaces.Provider<DbClient>>("Provider<DbClient>") 
     .toProvider<DbClient>((context) => { 
      return() => { 
       return new Promise<DbClient>((resolve, reject) => { 

        // Create instance 
        let dbClient = context.container.get<DbClient>("DbClient"); 

        // Open DB connection 
        dbClient.initialize("//connection_string") 
          .then(() => { 
           resolve(dbClient); 
          }) 
          .catch((e: Error) => { 
           reject(e); 
          }); 
       }); 
      }; 
     }); 

Затем вы можете вводить и потреблять поставщика. Единственная проблема заключается в том, что для этого требуется двухэтапная инициализация: инъекция constructor и метод async init().

class UserRepository { 

    private _db: DbClient; 
    private _dbProvider: Provider<DbClient>; 

    // STEP 1 
    public constructor(
     @inject("Provider<DbClient>") provider: Provider<DbClient> 
    ) { 
     this._dbProvider = provider; 
    } 

    // STEP 2 
    private async init() { 
     if (this._db) return this._db; 
     this._db = await this._dbProvider(); 
     return Promise.resolve(this._db); 
    } 

    public async getUser(): Promise<Users[]>{ 
     let db = await this.init(); 
     return db.collections.user.get({}); 
    } 

    public async deletetUser(id: number): Promise<boolean>{ 
     let db = await this.init(); 
     return db.collections.user.delete({ id: id }); 
    } 

} 

Мы работаем над new feature, чтобы упростить введение асинхронных значений. Эта функция будет включена в inversify 3.0:

class UserRepository { 

    // STEP 1 
    public constructor(
     @inject("Provider<DbClient>") private provider: Provider<DbClient> 
    ) {} 

    public async getUser(): Promise<Users[]>{ 
     // STEP 2: (No initialization method is required) 
     let db = await this.provider.someFancyNameForProvideValue; 
     return db.collections.user.get({}); 
    } 
} 
-1

Просто создать соединение при запуске приложения и связать уже подключенный экземпляр, как правило, вы действительно не нужно отложить подключение.