ES7 Dependency Injection

As if JS wasn’t fucking annoying enough

get out of here this is beautiful

Looks nice. Were you inspired by https://github.com/inversify/InversifyJS or is the @Inject syntax just an obvious design conclusion?

Was just an obvious name. Didn’t even know inversifyjs existed but it looks neat.

no thanks!

What is your preferred method of DI in JavaScript?

lmao I had a feeling this would come up. So explain to me how that is simpler than using decorators for ES6 classes? What could be more natural than accessing a dependency X using this.X – considering dependencies are just properties on an object? I also eliminate some boilerplate from bottlejs where you need to specify your dependencies during instantiation – something I believe should be done at the class definition. If you’d prefer to do that, it is still possible to do so using decorators; they’re just special function definitions. Can’t comment on factories and decorators because those features simple aren’t available yet.

The point of this library is to work naturally with ES6 classes… if you haven’t noticed already from the examples provided.

Bottlejs seems to be more of a dependency container than a dependency injection framework…

what’s happening here

Trying to inject some life into this dead section.

I meant what is dependency injection for and what is a use case

Dependency Injection (DI) is a language-agnostic design pattern used to help decouple a class from its dependencies. A dependency is some other class that is used by the current class. For a concrete example of that, say we have the following code:

[code=java5]class UserModel {
constructor(name, age) {
this._name = name;
this._age = age;
this._db = new Database();
}

save() {
// Save all user’s properties.
this._db.save(this);
}
}[/code]
Here we model a user whose properties are name and age. We also specify a database instance that is stored in this._db (you wouldn’t do this in practice but stay with me here…). In this example, the Database class is a dependency of the UserModel class. But notice that if we wanted to change the database (SQL vs. NoSQL?) in the future we would have to change all dependencies in every class. Perhaps we want to make a dependency dynamic? This logic doesn’t belong in the UserModel. A cheap “solution” is to do something like this:

[code=java5]class UserModel {
constructor(name, age, db) {
this._name = name;
this._age = age;
this._db = db;
}

save() {
// Save all user’s properties.
this._db.save(this);
}
}

const db = new Database(); // Could come from a factory, for example.
const user = new UserModel(‘Anthony’, 21, db);
// …
user.save();[/code]
Notice we just added a new constructor parameter but managed to decouple a particular type of Database from the user model. However this isn’t ideal because a UserModel shouldn’t have to worry about which Database to use. Also, we would now have to attach a database instance to each instance of a user model. This is where DI is useful.

InversifyJS will use “kernels” to automatically inject dependencies into the class so that this doesn’t need to be done explicitly. bottlejs will create a container for your classes that you instantiate from which resolves dependencies before returning to you the class. They refer to these classes as “services”. My goal is to take advantage of new syntax to reduce boilerplate and simplify dependency injection.

[quote=“justaguy, post:9, topic:555246”][quote author=Miss Silabsoft link=topic=674172.msg4507354#msg4507354 date=1461344051]


[/quote]

lmao I had a feeling this would come up. So explain to me how that is simpler than using decorators for ES6 classes? What could be more natural than accessing a dependency X using this.X – considering dependencies are just properties on an object? I also eliminate some boilerplate from bottlejs where you need to specify your dependencies during instantiation – something I believe should be done at the class definition. If you’d prefer to do that, it is still possible to do so using decorators; they’re just special function definitions. Can’t comment on factories and decorators because those features simple aren’t available yet.

The point of this library is to work naturally with ES6 classes… if you haven’t noticed already from the examples provided.[/quote]

Hi everyone, I’m the author of bottlejs.

@justaguy: I think there might be some misconceptions about how bottlejs works. With bottle, you do specify dependencies when defining the class, not when instantiating the class. In fact, after defining your services/factories/what-have-you, nothing has been instantiated until you request a service from the container. The services and deps are lazily loaded too, so the service itself (and its dependencies) are not instantiated until they are accessed.

That aside, the new syntax approach is interesting.

[quote=“young.steveo, post:15, topic:555246”][quote author=justaguy link=topic=674172.msg4507361#msg4507361 date=1461356568]

lmao I had a feeling this would come up. So explain to me how that is simpler than using decorators for ES6 classes? What could be more natural than accessing a dependency X using this.X – considering dependencies are just properties on an object? I also eliminate some boilerplate from bottlejs where you need to specify your dependencies during instantiation – something I believe should be done at the class definition. If you’d prefer to do that, it is still possible to do so using decorators; they’re just special function definitions. Can’t comment on factories and decorators because those features simple aren’t available yet.

The point of this library is to work naturally with ES6 classes… if you haven’t noticed already from the examples provided.
[/quote]

Hi everyone, I’m the author of bottlejs.

@justaguy: I think there might be some misconceptions about how bottlejs works. With bottle, you do specify dependencies when defining the class, not when instantiating the class. In fact, after defining your services/factories/what-have-you, nothing has been instantiated until you request a service from the container. The services and deps are lazily loaded too, so the service itself (and its dependencies) are not instantiated until they are accessed.

That aside, the new syntax approach is interesting.[/quote]

Very neat how you found this little (dead) corner of the internet! Welcome.

Thanks for the clarification too; I especially like how bottlejs lazy loads dependencies, and is something I’d like to look into as well. I’ll be sure to take a closer look at how bottle works when I get back to working on my own library to draw some inspiration.

I really need to get into github traffic analytics that’s bretty cool

Death Style, you busted me. :stuck_out_tongue:

Every so often I peruse the traffic analytics on Github to see who’s talking about or linking to my projects.