[英]How to inject an asynchronous dependency in inversify?
I have TypeScript application and I'm using Inversify for IoC. 我有TypeScript应用程序,我正在使用Inversify for IoC。
I have a connection class: 我有一个连接类:
'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 };
After I created my connection I want to bind a connection into my container: 在我创建连接后,我想将连接绑定到我的容器中:
kernel.bind<Connection>('DefaultConnection').toConstantValue(getConnectionManager().get());
and then I want to inject it into another class: 然后我想把它注入另一个类:
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;
}
So in my container configuration how can I bind DefaultConnection that needs to wait for CreateConnection I can do with async and wait but I'm wonder if there is a cleaner way to achive this in inversify 所以在我的容器配置中如何绑定需要等待CreateConnection的DefaultConnection我可以用async做等待但是我想知道是否有更简洁的方法来实现这个inversify
Inversify 2.0 includes support for asynchronous factories (AKA Providers) Inversify 2.0包括对异步工厂的支持(AKA提供商)
A provider allows you can to declare a provider as follows: 提供者允许您按如下方式声明提供者:
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);
});
});
};
});
Then you can inject and consume the provider. 然后您可以注入并使用提供程序。 The only problem is that it requires two-step initialization: the
constructor
injection and the async getDb()
method. 唯一的问题是它需要两步初始化:
constructor
注入和async getDb()
方法。
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 });
}
}
We are working on a new feature to simplify the injection of asynchronous values. 我们正在开发一种新功能来简化异步值的注入。 This feature will be included in inversify 3.0:
此功能将包含在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({});
}
}
只需在应用程序启动时创建连接并绑定已连接的实例,通常您不需要延迟连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.