-
Notifications
You must be signed in to change notification settings - Fork 1
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
Confused by specificity injector #2
Comments
Hey, I'll surely update the documentation as soon as possible but as I don't want to keep you waiting, I'll explain here. When you do As for why we would ever want this to happen there are three ways to answer this.
I recognize that there are better and many more examples to explain this I hope this will do. Please let me know if I can help you with anything else, I'll get started on a new and improved documentation ASAP. |
Thank you for your quick response!
I think I grok your reasons. But what if you want to inject D at one point in the dependency tree, and A in another? While one can design the class hierarchy such that that won’t be the case, it makes me uncomfortable that the default behavior is that the programmer would have have that in mind when designing classes.
Maybe I’ll feel totally differently when I’ve used it for a while, but I just wanted to share that initial response. To be a little fuller in my response, I’m reminded of the choice to design coffeescript such that variables can’t be shadowed, which must have seemed like a good idea at the time, but led to all sorts of issues including seriously reducing enthusiasm for the language.[1] An alternative would be to have two different get() methods, maybe get() and deep_get() or something like that. Where the one with this behavior would be somehow indicated in the name.
One situation that comes to mind about why I would not want this behavior: Suppose I have a class hierarchy where both a parent and a subclass are useful in different contexts. I’ve certainly had designs like that. In the context of dependency injection, one part of the code may want different parameters passed to the parent class for different situations, and the other part of the code might actually want the subclass. So I’d like to be able to inject an instance of the parent class with one set of parameter values for production use and another set for testing; but I also need to inject the child. I’m not sure how I’d do that with the existing get(). Maybe use two different containers?
But if there were separate get() and deep_get() methods, it wouldn’t be an issue at all. It would be clear how to do what I want to do, and the behaviors would be somewhat expected by a newcomer reading the code just by looking at the function names. At least she’d know that something different was probably happening with deep_get(), which she could look up in the docs.
But again, I’m only STARTING to to use autocontainer, so maybe I’ll feel totally 180 degreed differently with more experience and knowledge about the library! :) These are just very initial thoughts.
Thanks again,
Gary
[1] https://donatstudios.com/CoffeeScript-Madness
…--
Gary Robinson
[email protected]
http://www.garyrobinson.net
On May 3, 2020, at 11:15 AM, Omran Jamal ***@***.***> wrote:
Hey, I'll surely update the documentation as soon as possible but as I don't want to keep you waiting, I'll explain here.
When you do container.get(A) the returned object is an instance of class D not A. As D inherits from A, it is also effectively an instance of A hence both asserts to be true.
As for why we would ever want this to happen there are three ways to answer this.
The Abstract: Each time you extend a class you usually make the child class more feature rich and more useful or 'smart' or efficient but always make sure to keep the original functionality intact so when a function is hinted to need any instance of a base class it is (in some people's opinion) smart to inject the class farthest down the hierarchy.
The common sense: When I create an abstract class Fruit to represent fruit and I have a function makeFruitSalad(fruit: Fruit) that makes a fruit salad, it makes sense that I would want an instance of Mango instead of a bare-bones Fruit class.
The real world: More of then than not this is very useful for testing, when I have a large application and I have a class MagicClass I want to stub it and gather data about another function or class that communicates with MagicClass in that case I can just extend MagicClass and created FakeMagicClass and give it to the container so that I don't have to change my actual code being tested which is a sigh of relief.
I recognize that there are better and many more examples to explain this I hope this will do.
Please let me know if I can help you with anything else, I'll get started on a new and improved documentation ASAP.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#2 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAIUA7OS4Z7JASXEPJYEKLTRPWYEPANCNFSM4MYFSWYQ>.
|
That's a great and sensible idea, I might implement that in the next major version! I wont argue at all against what you said up there the only reason I coded this behavior is because I wanted to emulate the type hint by interface and abstract class like in Java but in Python. Now that I think of it, it is in fact possible to achieve this in other ways. Even though I might not implement In the case if Thanks for the moment of induced epiphany btw! |
I’m not sure what you mean by “hinted”. I think you mean
container.singleton(A, 'apple')
…so if only one of A and B has a hint such “apple” above, that will be the one that is injected.
Seems like something like that could create the needed control!
Thanks for considering this issue! I am greatly looking forward to playing more with this...
--
Gary Robinson
[email protected]
http://www.garyrobinson.net
… On May 3, 2020, at 12:38 PM, Omran Jamal ***@***.***> wrote:
That's a great and sensible idea, I might implement that in the next major version! I wont argue at all against what you said up there the only reason I coded this behavior is because I wanted to emulate the type hint by interface and abstract class like in Java. Now that I think of it, it is in fact possible to achieve this in other ways.
Even though I might not implement deep_get() and get() as separate methods (that would really mess up the "auto" part). I'll probably decide based on explicitness. If you explicitly register A and B where B happens to extend A, the container will inject B if B is hinted and A if A is hinted.
In the case if A is not explicitly registered and only B is registered, the container will inject B if A is hinted. How does that sound?
Thanks for the moment of induced epiphany btw!
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#2 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAIUA7MBJWPWJ23UMYEDTILRPXB3TANCNFSM4MYFSWYQ>.
|
First I want to say that I'm new to dependency injection in general, but in the last week have experimented with the dependency-injector library, which seemed much more cumbersome to use than the injector library (which I also tried), which in turn seems much more cumbersome to use than autocontainer. So at this point I have to say that I'm very impressed with autocontainer and look forward to trying to use it in an upcoming project where I think dependency injection could be very helpful.
But, I'm confused by the Specifity Injector functionality described in an example on your main page. In the example, class D inherits from class A; class A does not inherit from class D. But the object retrieved with container.get(A) apparently inherits from both A and D, based on the results of the isinstance() asserts. This doesn't make sense to me. Why is that happening? Why would I even want it to happen?
It seems like it could be a good idea for the documentation to explain this.
The text was updated successfully, but these errors were encountered: