Replies: 7 comments 1 reply
-
Hey @c100k, as said in #1410, I am afraid the container is not so simple. The binding dictionary is private for some very good reasons:
I don't think we should expose this dictionary for now. We might extend the container API with a |
Beta Was this translation helpful? Give feedback.
-
Hi @notaphplover, Thanks for your explanation. Indeed, it makes a lot of sense. The use cases described in this issue are "read-only", so a Happy to help, develop, test or simply debug if need be. |
Beta Was this translation helpful? Give feedback.
-
Hey @c100k
To be honest I need as much help as possible, I want to continue maintaining the library after a couple of years not being properly maintained. If you are interested in submiting a PR, allow me to give you my 5 cents: Implementation notesIntroduction
What to returnWe should probably return the result of merging clones of the container How would we merge a Lookup?Given
This way merging a child in a parent overrides services the same way we want. Keep in mind this operation is asociative (merge(merge(a, b), c) is the same as merge(a, merge(b, c))). This would be implemented in a How do we implement
|
Beta Was this translation helpful? Give feedback.
-
I actually would like to see a real good use case on why you would like to access what is inside of the If your reason is testing, you're actually violating the basic idea of the library which is to provide you a consistent, reliable and trustworthy ecosystem in which you can implement your functionalities or system on top of the container mechanic. The reason why the Now, if the use case is different resolution strategies, we can discuss those, are those strategies being aimed for. Or maybe you want to design a library that integrates well with the container but for this you need access to the bindings, or maybe the application itself can adjust its own behavior based on a specific configuration of certain bindings. Look, all these ideas above are just hypotheses of potential implementations, they don't reflect what this ioC should have at the moment. I was just comparing Inversify with Microsoft iOc (https://github.com/microsoft/tsyringe) is very minimalist and doesn't have a bunch of things Inversify already have. I think for this one, we just need to find a real good use case to have this exposed. I honestly have mutability, security and performance concerns, without having a proper use case to study. (Basically, what are you trying to achieve) A suggestion of implementation would a function like this, if you pass the serviceIdentifier it will return the bindings for you, otherwise if nothing is passed, it will return all bindings. public listBindings(serviceIdentifier?: interfaces.ServiceIdentifier<unknown>): ReadonlyArray<{ serviceIdentifier: interfaces.ServiceIdentifier<unknown>; bindings: ReadonlyArray<interfaces.Binding<unknown>> }> {
const bindingsList: Array<{ serviceIdentifier: interfaces.ServiceIdentifier<unknown>; bindings: ReadonlyArray<interfaces.Binding<unknown>> }> = [];
this._bindingDictionary.traverse((key, value) => {
if (!serviceIdentifier || key === serviceIdentifier) {
bindingsList.push({ serviceIdentifier: key, bindings: Object.freeze([...value]) });
}
});
return Object.freeze(bindingsList);
} Example of return: @injectable()
class A {
public name: string;
public age: number;
}
@injectable()
class B {
public name: string;
public age: number;
}
@injectable()
class User {
public name: string;
public age: number;
}
const container = new Container();
container.bind(User).toSelf();
container.bind(A).toSelf();
container.bind(B).to(User);
container.bind(User).to(B);
console.log(container.getBindingDictionary(B)); Return
Tell me if make sense to you, then we can close this issue until you find a good real use case in which we can study and provide you a good solution. What are your thoughts? |
Beta Was this translation helpful? Give feedback.
-
Hey @rsaz, thank you for giving your perspective.
To be really honest, agree. Inversify has way too many features to be maintained, and we should have a really good use case in order to provide this feature. @c100k could you give us a minimum example in which you would find this feature useful?
Yeah, performance might be a concern here. I would say mutability and security issues can be easily solved using clones.
I feel returning container bindings feels incomplete with the existence of parent containers. |
Beta Was this translation helpful? Give feedback.
-
Hi @rsaz, Thanks for your insights. Here is a typical use case I'm facing: I'm building a library/framework on top of Inversify allowing developers to build business applications faster (not released yet). By default, the library comes with a preconfigured CryptoManager : CryptoManager <-- NodeCryptoManager [type: Instance] [scope: Transient]
DateTimeManager : DateTimeManager <-- LuxonDateTimeManager [type: Instance] [scope: Transient]
EmailManager : EmailManager <-- FakeEmailManager [type: Instance] [scope: Transient]
EnvironmentManager : EnvironmentManager <-- NodeEnvironmentManager [type: Instance] [scope: Transient]
FormDataBuilder : FormDataBuilder <-- NodeFormDataBuilder [type: Instance] [scope: Transient]
FSManager : FSManager <-- NodeFSManager [type: Instance] [scope: Transient] Note that I'm not facing any issues with any parent containers (as mentioned by @notaphplover) since I only have one container, to keep things simple for now. The library/framework also comes with auto-testing features so the idea is to check if everything is bound correctly. For example, we would alert the developer if for a production environment, they kept I agree that for this last use case, I can check dependencies one by one with the A last use case I see maybe, is to detect forgotten bindings statically instead of at runtime. Indeed, with the right reflection usage, one can check what is injected in their classes and compare it with what is bound in the container. And on the other hand, it could also detect obsolete bindings. PS : @notaphplover thanks for suggesting how this would be implemented. Even though we don't more forward, it's a great learning to understand how the library works. |
Beta Was this translation helpful? Give feedback.
-
Hi @c100k thanks for your reply. I am happy that you're creating a lib/framework with Inversify. Keep us informed so that we can use your tool in the future and provide feedback as well. I built ExpressoTS Framework (https://expresso-ts.com/), the third most downloaded framework for building backend API's, just behind Koa and Nestjs. ExpressoTS is powered by Inversify as well, that's why I decided to support the project. Now we do have two different templates when opening issues, one for "Fixing Bugs" and the other for "Community Ideas" in which this request would fall into. When you're ready, with a good use case for this request, open a community idea (feature request), and we go from there to generate a proper documentation to start implementing this feature. Your idea is not bad at all, as I said, it just needs to have a strong argument to be build, especially in this phase 1, where me and @notaphplover are working to reorg the project and make sure is clean and set to success. I am closing this ticket if you don't mind! |
Beta Was this translation helpful? Give feedback.
-
For multiple reasons, it can be useful to access a container's bindings : write some tests, check that the bindings are correct, export the bindings to a human readable format, etc.
Possibly related topic : #1410.
Expected Behavior
The
Container
has a_bindingDictionary
field (https://github.com/inversify/InversifyJS/blob/master/src/container/container.ts#L25). Since the field is private, we could add a public getter for it.Current Behavior
Right now, there is no getter so the only workaround is to access the field telling TypeScript to stop complaining with
@ts-ignore
.Even if it "works", it's hacky and not very ideal. Because of
@ts-ignore
, if for any reason inversify is updated and this field is renamed/removed, tsc won't complain and it will cause an error at runtime.Possible Solution
Adding a getter to access the bindings map.
Steps to Reproduce (for bugs)
N/A
Context
N/A
Your Environment
Stack trace
Beta Was this translation helpful? Give feedback.
All reactions