jaredhanson / electrolyte

Elegant dependency injection for Node.js.
MIT License
564 stars 59 forks source link

Manually adding an object to the container #35

Open spruce-bruce opened 8 years ago

spruce-bruce commented 8 years ago

I'm using hapi.js and I'd like to add the hapi server object to my electrolyte container while at the same time maintaining some of hapi's best practices.

The hapi server object maintains its own container of plugin objects, and a typical way to set up a hapi project is to use a 'bootstrap' plugin to set up the server. Mine looks like this:

var ioc = require('electrolyte');
var config = require('./config');

exports.register = (server, options, next) => {
    server.auth.strategy('jwt', 'jwt', {
        key           : config('/auth/secret'),
        validateFunc  : require('./src/application/auth/validateJWT'),
        verifyOptions : { algorithms: [ 'HS256' ] }
    });

    ioc.use(ioc.node('src/application'));
    ioc.use(ioc.node('src/lib'));

    server.route(ioc.create('example/example-routes'));
    server.route(ioc.create('auth/auth-routes'));
    server.route(ioc.create('user/user-routes'));

    next();
};

exports.register.attributes = {
    name    : 'ims-bootstrap',
    version : '0.0.1'
};

I want to make the server object that is passed into this plugin available in my electrolyte container. Is there some way to call ioc.use such that it will just make the already instantiated server object available in the container?

spruce-bruce commented 8 years ago

Sort of answering my own question, here. I did this:

    ioc.use(function(id) {
        if (id === 'server') {
            server['@literal'] = true;
            return server;
        } else {
            return;
        }
    });

Which is essentially the same code that's found in the node_modules loader. This seems to work just fine so far... I'm wondering if there's any obvious problem with this that I'm missing?

hoxxep commented 8 years ago

That's a neat workaround to add individual objects into electrolyte. Note the else ... return statement is not needed though, as the function returns the same value, undefined, without it.

ioc.use(function(id) {
    if (id === 'server') {
        server['@literal'] = true;
        return server;
    }
});
spruce-bruce commented 8 years ago

Indeed!

Thanks :)

konstantinkrassmann commented 8 years ago

in Version > 0.1 (0.0.6) there was

ioc.literal("server", {});

Which is now an undocumented breaking change...

spruce-bruce commented 8 years ago

So you don't know why that was removed?

konstantinkrassmann commented 8 years ago

Singleton got renamed to literal, which broke the old meaning of it.

angelwithaneye commented 7 years ago

Thanks for this. Super basic need for a DI framework.