ecowden / pluto.js Goto Github PK
View Code? Open in Web Editor NEWJavaScript Dependency Injection
License: MIT License
JavaScript Dependency Injection
License: MIT License
This is a toughy.
Lazy loading makes sense for fast startups, but it means that we can't guarantee that any given factory function ever gets called. So, if I'm relying on, for instance, Express routes getting registered, I can't.
Possible options:
module.start()
kinda function that does the above.bind()
(bindAndCreate()
?) that will mark the binding for eager loading. Or extend the binding vocabulary to be something like (bind(...).toFactory(...).andEagerLoad()
). I kinda like the previous option better because it would be easier to scan through and see what is simply bound and what is set to be initialized.Pluto bootstrapping fails without evidence when two or more functions are dependent on each other. Perhaps an error could be thrown if this situation occurs.
serviceOne.js
module.exports = function(serviceTwo) {
...
}
serviceTwo.js
module.exports = function(serviceOne) {
...
}
As the project owner, I want a CI tool building my project so that I get test results and simplified deployment.
Let's make this a proper Node/NPM module
After we have asynchronous injection (#25), the old .eagerlyLoadAll(...)
doesn't make as much sense. Instead, this is our opportunity to "bootstrap" the whole shebang (probably the whole application). It should try to load all injectables, resolve all promises as needed, and return an object holding the fully bootstrapped set of components.
const anInstance = Promise.resolve({}) // Promises will be resolved
const bind = pluto()
bind('myInstance').toInstance(anInstance)
// ... eagerly load everything. Maybe `.bootstrap()`?
const app = yield bind.eagerlyLoadAll()
// ...and then everything can be retrieved synchronously
t.is(app.get('myInstance'), anInstance)
Back when I originally made this, I was targeting browsers and Node.js v0.8.x. (Also, it's about the first thing I ever wrote in JavaScript.) Dynamically invoking constructor functions was black magic, so I relied on a big ol' switch statement.
Nowadays, this should be easier to work around.
The weird callback thing is just ugly. Instead, consider something cleaner:
const pluto = require('pluto')
const bind = pluto()
const myInstance = {}
pluto.bind('myInstance').toInstance(myInstance) // and other bindings
const promise = pluto.get('myInstance') // get(...) must return a promise to support async
promise.then( (result) => {
t.is(result, myInstance)
})
As a developer, I want to clean up the module loading code duplicated in the tests so that there isn't ugly copy pasta in my codebase, and so that adding new tests is easier.
I'm really not sure if this is a good idea or a terrible idea...
We've gotten very used to Angular-style dependency injection. Since Angular has gotten so much traction, it seems to make sense to adopt a similar API.
I could pretty easily adjust the API to look like:
pluto.module('myModule')
.factory('myFactoryFunction', function(dependencyOne, dependencyTwo) {
...
});
...but then there's artifacts (like a name for the module, or module dependencies) which don't seem to make sense for Node. There's no "multiple modules got loaded by the browser" thing - it's all just require(...)
calls.
Guice-style bootstrapping seems to make more sense.
There's already plenty of module
s out there. In particular, Node's module, which just happens to be a kinda-sorta huge concept and global variable in the Node world.
Let's get rid of the 'module' nomenclature in favor of something a bit less vague.
As the project owner, I want documentation on how to integrate Pluto into a project so that people can get started easily.
Create an example app.
Consider using an Express application, since it's such a popular framework.
I'd also love to have a kata example that I can use as a template.
My understanding of JavaScript has grown a lot since I first created this:
var
sAs the project owner, I want an integration test suite so that I have greater confidence in the project from end to end.
As a developer, I want an error if I try to use something other than a String for a name so that I don't screw things up.
Pluto should support asynchronous bootstrapping by automatically detecting and resolving promises, then injecting their resolved values when used as a dependency.
Sample usage:
function Greeter(name) {
this.name = name
}
Greeter.prototype.greet = function () {
return `Hello, ${this.name}!`
}
const bind = pluto()
bind('name').toInstance(Promise.resolve('World'))
bind('greeter').toConstructor(Greeter)
const theGreeter = yield bind.get('greeter')
t.is(theGreeter.greet(), 'Hello, World!')
I should officially add a license file.
I'm thinking the MIT license makes the most sense.
I was young, I was naive, I checked in .iml and .idea files...
Calls to module.get(...)
should be memoized. This effectively turns everything injectable into singletons.
It should be safe to create a factory function (or constructor function) and know that it will only be called once.
Are there times when we wouldn't want singletons? I can't think of any off the top of my head, and it should be simple enough to get the desired behavior by having a singleton factory that creates instances.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.