zazoomauro / node-dependency-injection

The NodeDependencyInjection component allows you to standarize and centralize the way objects are constructed in your application.
https://github.com/zazoomauro/node-dependency-injection/wiki
MIT License
280 stars 34 forks source link

async support / async factories #153

Closed roboticflamingo closed 4 years ago

roboticflamingo commented 4 years ago

I have a factory which has a create method that needs to be 'await'ed? Is this supported / a work around available?

This is especially handy for ORM repositories wrappers and EntityManagers - see example below.

See below: app.orm: factory: class: 'src/lib/orm/MikroOrmFactory' method: 'create'

app.userProfile.repository: class: 'src/repositories/UserProfileRepository' arguments:

when I call UserProfileRepository's constructor - it receives a Promise rather than the awaited ORM manager instance (per request):

🚀 Server ready at http://localhost:4000/graphql em Promise { } UserProfileRepository { getAll: [AsyncFunction (anonymous)], getOneByUuid: [AsyncFunction (anonymous)], getOneByEmail: [AsyncFunction (anonymous)], createQueryBuilder: [AsyncFunction (anonymous)], orm: Promise { } }

roboticflamingo commented 4 years ago

Closing as caused by an ordering bug not in library code.

dimabory commented 3 years ago

Same issue here... @roboticflamingo How did you resolve it?

cc @zazoomauro

Use case:

// ./foo.repository.js
class FooRepositpry {
 #connection;
 constructor(connection) {
    // always getting Promise here
    this.#connection = connection;
 }
 async findOne(id) {
  // still Promise instance what causes `this[#connection].query is not a function`
  const [first] = await this.#connection.query(`SELECT * FROM foo WHERE id = ${id}`);
  return first;
 }
}
// ./container.js
const { ContainerBuilder, Reference, Definition } = require('node-dependency-injection');
const FooRepository = require('./foo.repository');
const initMysqlConnection = require('./mysql');

const mysqlConnectionDefinition = new Definition();
mysqlConnectionDefinition.setFactory(
  class {
    static async init() {
      return await initMysqlConnection();
    }
  },
  'init',
);
container.setDefinition('mysql.connection', mysqlConnectionDefinition);

container.register('foo.repository', FooRepository, [new Reference('mysql.connection')]);

container.compile();

module.exports = container;