-
Notifications
You must be signed in to change notification settings - Fork 726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internally generate symbols/identifiers; optional-identifiers-happy-path? #534
Comments
Hi @atrauzzi, thanks for thinking about ways to improve inversify and sharing them. I really appreciate it. I've been reading the links from laravel and I saw:
This is almost the same in Inversify. When we use classes (not interfaces), the only required annotation is When you use We would need something like: import "./entities/someInjectable1";
import "./entities/someInjectable1";
import "./entities/someInjectable1";
import "./entities/someInjectable1";
import "./entities/someInjectable1"; This is how the It would be much nicer if all the classes where loaded automatically but this is not possible due to the lack of fully featured reflection in JS. In Node.js we can write a function that reads a directory in the file system and loads every module but in browsers things are much more complicated. Also, my understanding is that in the future the I originally though about using naming or path conventions (that is how version 1.0 of inversify worked) but I don't think that is a good idea because I believe that the main features of InversifyJS is being a universal library that work in browsers and node, it is agnostic of frameworks and architectures. I also tried to allow InversifyJS so people can build frameworks in top of it and create great developer experiences. We could improve the Inversify experience but that would mean being less flexible. I'm open to examine examples if you want to try ideas but I see this more as a side-project library specific for a concrete architecture and framework. |
Yeah, definitely appreciate the differences in the JS space because it doesn't offer an autoloader pass the same way as PHP (if a class isn't found, you can plug a loader in as a last ditch to discover it before failing). That all said, my imagination may be getting the better of me here... I still think these things might be possible. If we think through how people will do their bindings, would it not be safe to assume that every class they'll want will have to have been imported at least once because they'll be pulling in that reference (to the constructor/static/class-type); prior to inversify's first attempt to work with it? Not sure if that's the most effective way to express what I'm thinking, but the order of everything actually works out. The TS interface thing sounds like it can't come soon enough but with an object, you could generate some kind of fingerprint from the signature of the interface-object-meta-thingy. It's all duck-typed after all ;) The name and path conventions I totally agree on. Inversify should be zero-convention when it comes to physical project structure. I'll take care of that with protoculture ;) I'd have to spend some while looking at the code for inversify to understand where these opportunities are to pre-populate the metadata and what the right things to do are. But I'm slightly curious because even the little bit of metadata being generated now may be enough. |
Hi @atrauzzi I think things are likely to head this way. My vision about this right now is that I want to wait until there is a clear vision of where TypeScript is heading. If they are going to implement reflection for interfaces, then there are no need for custom transforms. If they are not going to do it, then using transform could be an option but I see the transforms as something that would live outside of the core repo. You can see how people is already testing some of this stuff. |
Yeah, overall I agree. From protoculture's side, I'll just continue "passing along" the code debt for managing those pointers. Then once the winner of all this is determined, most of these concerns will turn into noops. Just something we all have to be aware of in TypeScript land until the dust settles 😄 Feel free to close this or leave it as a bookmark? |
Thanks for understanding my point of view. Let's hope the future is more clear soon 👍 |
I'm interested in knowing if there could be a way where symbol/identifier management isn't mandatory when using inversify for certain types of injections.
I feel like I mostly understand why they exist and what purpose they serve (some injections don't correspond to a distinct type).
Some point-form thoughts
reflect-metadata
should be helping with?The idea is that you have a scenario where the IoC becomes minimum-touch. It's a convention where the container only receives queries for instances by their static type and - barring any overrides - uses reflection to do the rest. Instead of it being mandatory to painstakingly describe the connections between types, you simply have to ensure your constructor parameters are clearly defined. With Laravel, you don't even have to inform the container of a type prior to looking it up! Actually, as far as I can tell, internally I think the Laravel DI system only uses strings to track types.
In the case of inversify and TypeScript/ECMAScript, the equivalent here would be to internally generate symbols/identifiers whenever the container sees a new type. Then, subsequent "naked" lookups of the type would result in that same - already established - symbol being internally rediscovered and used.
What this might eliminate
(please correct me if I'm wrong here!)
@injectable
on classesI'd effectively be able to say
context.get(MyStaticType)
and get back an instance, having done no other preparation in advance.What this would not eliminate
Why?
Mainly to reduce boilerplate, code maintenance, and the margin of cognitive overhead that comes with them. As I've been putting together my first non-contrived protoculture solution, I've discovered that because I'm using inversify, implementers are forced into managing their own symbols. Even though they may not be adding any ambiguous types to the container.
My first instinct was to try and hide this by managing the symbols/identifiers myself in some of my framework classes. But then my mind started pushing that responsibility down...down...down.
Which eventually got me to thinking about whether there could be a way to avoid these requirements entirely provided a specific set of rules were observed. And of course, with Laravel serving as an example, I'm sure there could be a way to have inversify offer the same. This is a total guess - but I don't think it would be too disruptive either?
This idea would go nicely with what's already been done here: #505 - in fact, when selectively designed for it, a request for a type could effectively cause its entire dependency graph to self-wire.
And of course nothing I'm suggesting here implies that the existing mechanisms to bind types should be eliminated. So caveats in the dependency graph can still be accommodated and self wiring would just continue beyond and around it.
More than happy to go into an extended discussion about this if needed. But I feel like it should be possible and would take this already great (I'm not going anywhere!) container and push it to yet-even-higher-heights.
🖋️
The text was updated successfully, but these errors were encountered: