2

我有TypeScript應用程序,我正在爲IoC使用Inversify如何在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用於創建連接 我可以做異步等待,但我不知道是否有在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

只需創建應用程序啓動時連接並綁定已連接比如,通常你並不真的需要推遲連接。