intravenous icon indicating copy to clipboard operation
intravenous copied to clipboard

How about get by Function rather than key?

Open tusharmath opened this issue 9 years ago • 10 comments

The Problem statement

If I want to retrieve an instance of MyCustomClass, I have to first register it with a key name. For that I will have to require this and all the other modules on startup. That means one file will have to require all the modules first and then initialize the application.

This seems in efficient and quite a headache to maintain that one file which contains all the required modules.

RATHER: How about requiring them in modules that actually need them instead

var Dep1 = require('./dep1');
var Dep2 = require('./dep2');

function MyCustomClass () {}
MyCustomClass.$inject = [Dep1, Dep2]; //Instead of using key name

So the main idea is to be able to query on the Class name rather than the key name. What do you think?

tusharmath avatar Sep 03 '14 06:09 tusharmath

This seems like a very specific use case. It would be auto-registering singletons that don't have any dependencies themselves (e.g. Dep1 cannot have any dependencies that come from the container).

If that's what you want to do, I think it would make more sense if you would create a simple wrapper around require that handles auto-registration based on filename. Make sure it also keeps working once you minify.

sagacity avatar Sep 03 '14 09:09 sagacity

Why can't Dep1 have dependencies injected in the same way? My idea is not a specific use case, infact that is what is being practiced by - AngularDI

tusharmath avatar Sep 03 '14 18:09 tusharmath

Okay, I guess it depends on how you set up the modules you require, of course! I do prefer the explicitness of the registration step though.

Hmm, how would you specify the lifetime of the modules, if you skip the registration step?

sagacity avatar Sep 04 '14 07:09 sagacity

Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file. source

Which means that the module's lifetime is the basically equal to the lifetime of the app. So technically you don't really have control over it. But you have control over object instantiation which is a completely different process and that what your DI module is perfectly doing.

The design philosophy I am referring to makes you not want to load all the modules initially but instead load them as and when needed.

Your approach is great and works really well provided that module is already registered.

Say module A needs B. To be able to create an instance of A I would need to create an instance of B. So to use A I need to register B first - container.register('b',B), which is supposed to be done manually and then create an instance of A using intravenous. In my mind I need to make sure that I do a require('../B') before I ask for an instance of A, and there is not restriction where I should do this.

I hope you are getting my point here.

tusharmath avatar Sep 04 '14 14:09 tusharmath

Yes, I get that :) Thanks for the details, still. I'm just not sure how you would make sure that B can be instantiated as a singleton, per-request or unique?

sagacity avatar Sep 05 '14 11:09 sagacity

Exactly the way you were doing it earlier. Only difference is I don't pass the keyname (First Parameter). Neither do query on it.

tusharmath avatar Sep 05 '14 11:09 tusharmath

Ok, if you can provide a pull request I'd be more than happy to merge it in.

sagacity avatar Sep 05 '14 12:09 sagacity

Great! on it!

tusharmath avatar Sep 05 '14 12:09 tusharmath

I was not able to get enough time to work on this pull request. My approach would be to use es6 Map.

tusharmath avatar Jan 31 '15 14:01 tusharmath

@tusharmath what you are saying defeats the whole purpose of DI. Imagine you have 10's or more classes all depending on the Dep2 dependency and you have required Dep2 in all of them. Tomorrow if you decorate or extend your Dep2 with new Class you will have to go and change the require statement in all the 10 places (or more) and chances are very likely that you will miss it one or other class.

vipreshjha avatar Jan 18 '16 12:01 vipreshjha