young-steveo / bottlejs

A powerful dependency injection micro container for JavaScript applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Help with IoC in registering modules

tagyoureit opened this issue · comments

This might be a simple question, but...

I'm trying to get Bottle working in my app. Looking to use bottle.container.xyz inside a module. that I'm adding to bottle.

I tried to various ways to accomplish this (including trying to use #7 (comment)), but have not been able to be successful. Some help would be much appreciated!

Specifically, I'm trying to do something like...

//index.js*******************************************
var Bottle = require('bottlejs')
var bottle = new Bottle();

bottle.constant('c', require('./lib/constants.js'))
bottle.constant('logger', require('./lib/logger.js'))
bottle.container.logger.info('Constant packetfields: ', bottle.container.c.levels[1])
//*************************************

//constants.js****************
const levels = exports.levels = {
    1: 'info',
    2: 'silly'
}
//*********************************

//logger.js************************
var winston = require('winston')
var logger = module.exports = new(winston.Logger)({
    transports: [
        new(winston.transports.Console)({
            level: bottle.container.c.levels[1],
            stderrLevels: []
        })
    ]
});
logger.warn('WINSTON LOADED')
//*************************

The bottle.container.c.levels[1] is what I'm having trouble with in logger.js.

thanks!

@tagyoureit If you want to use the same bottle instance in two files in node, you'll want to name it and use Bottle.pop instead of new Bottle. This should work:

// index.js
var Bottle = require('bottlejs');
var bottle = Bottle.pop('yourInstanceName');
bottle.constant('Foo', true);
// logger.js
var Bottle = require('bottlejs');
var bottle = Bottle.pop('yourInstanceName');

bottle.container.Foo; // true

However

the above will only work if index.js is loaded before logger.js is loaded, because the code in logger is executed immediately. This can start to cause you a lot of headaches in a bigger app.

Instead, you should not register logger as a constant. You'll want to register logger with something like a a factory. For example, with a factory:

var winston = require('winston');
module.exports = function(container) {
    var logger = new(winston.Logger)({
        transports: [
            new(winston.transports.Console)({
                level: container.c.levels[1],
                stderrLevels: []
            })
        ]
    });
    logger.warn('WINSTON LOADED');

    return logger;
};

This way, it doesn't matter which file is loaded first.
Barring that, you could also use the register method defined here.

Hope that helps.