user4092086 user4092086 - 2 months ago 29
TypeScript Question

How can I inject knex using inversify?

How can I initialise knex and use Inversify dependency injector to inject it in

every where that i needed?

Answer

I have never used Knex but I'm the author of InversifyJS I will try to help you.

Based on the Knex docs you can do the following:

var knex = require('knex')({
  client: 'mysql',
  connection: {
    host : '127.0.0.1',
    user : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test'
  }
});

I also found the TS the types here.

I assume that what you want to inject is the knex instance. You could do the following:

import * as Knex from 'knex';
import { Kernel } from "inversify";

// configuration
let configuration: Knex.Config = {
  client: 'mysql',
  connection: {
    host : '127.0.0.1',
    user : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test'
  }
};

// instance
let knex: Knex = Knex(configuration);

let kernel = new Kernel();
kernel.bind<Knex>("Knex").toConstantValue(knex);

That way knex would be a singleton. If you don't want it to be a singleton you will need a factory:

 import * as Knex from 'knex';
 import { interfaces, Kernel } from "inversify";

 kernel.bind<interfaces.Factory<Knex>>("Factory<Knex>")
       .toFactory((ctx: interfaces.Context) => {
           return Knex({
               client: 'mysql',
               connection: {
                   host : '127.0.0.1',
                   user : 'your_database_user',
                   password : 'your_database_password',
                   database : 'myapp_test'
               }
           });
       });

You could also separate the config:

 import * as Knex from 'knex';
 import { interfaces, Kernel } from "inversify";

 kernel.bind<Knex.Config>("KnexConfig").toConstantValue({
     client: 'mysql',
     connection: {
         host : '127.0.0.1',
         user : 'your_database_user',
         password : 'your_database_password',
         database : 'myapp_test'
     }
 });

 kernel.bind<interfaces.Factory<Knex>>("Factory<Knex>")
       .toFactory((ctx: interfaces.Context) => {
           let config = context.kernel.get<Knex.Config>("KnexConfig");
           return Knex(config);
       });

These solutions provide you with a factory:

let knexFactory = kernel.get<interfaces.Factory<Knex>>("Factory<Knex>");
let knex = knexFactory();

The factory can be injected into other classes using an @inject("Factory<Knex>") annotation.

If you don't want to use a singleton and don't use a factory then you will need a dynamic value injection:

kernel.bind<Knex>("Knex").toDynamicValue((context: interfaces.Context) => {
    return Knex({
        client: 'mysql',
        connection: {
            host : '127.0.0.1',
            user : 'your_database_user',
            password : 'your_database_password',
            database : 'myapp_test'
        }
    });
});

The dynamic value injection will inject a new knex instance. Not a singleton and not a factory:

let knex = kernel.get<Knex>("Knex>");

Please note that I haven't tests these suggestions. I hope they will lead you in the right direction.

Comments