如何在反转中注入异步依赖?

时间:2016-11-30 04:40:23

标签: node.js typescript inversion-of-control inversifyjs typeorm

我有TypeScript应用程序,我使用Inversify作为IoC。

我有一个连接类:

'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;
        }

因此,在我的容器配置中,如何绑定需要等待CreateConnection的DefaultConnection 我可以做异步并等待,但我想知道在inversify

中是否有更清晰的方法来实现这一点

2 个答案:

答案 0 :(得分:10)

Inversify 2.0包括对异步工厂(AKA Providers)的支持

提供商允许您按如下方式声明提供者:

export class TagComponent implements OnInit {

    private buchungPos : BuchungPos;

    constructor( private readBuchungenService : ReadBuchungenService) { }

    ngOnInit() {
      this.readBuchungenService.observer_data.subscribe(
            function (data) {
               this.buchungPos = data.data;
            }.bind(this)
        );
    }
}

然后您可以注入并使用提供者。唯一的问题是它需要两步初始化: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 getDb()

我们正在研究new feature以简化异步值的注入。此功能将包含在inversify 3.0中:

class UserRepository { 

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

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

    // STEP 2
    // Get a DB instance using a provider
    // Returns a cached DB instance if it has already been created
    private async getDb() {
        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.getDb();
        return db.collections.user.get({});
    }

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

}

答案 1 :(得分:0)

只需在应用程序启动时创建连接并绑定已连接的实例,通常您不需要推迟连接。