-
Notifications
You must be signed in to change notification settings - Fork 81
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
Registering different implementations of the same interface. #108
Comments
Hi.
Inject is specifically designed to represent an application is a typed object graph. It simplifies reasoning about the whole application.
Please, take a look at the example in this comment #104 (comment)
In my opinion, it imitates different types in a custom way. It is usually better to just create different types for different use cases. |
Hi 👋
I get the idea, but when we talk about typed object graph, does it imply that a node can have one child only ?
I did check that, but it's confusing to do that for different reasons:
Sure, but i still believe it could use a type binding too. Like, I want this implementation of that interface, but now that I think of it, I am guessing this could be done with the class Interface(ABC):
def method(self):
pass
class ImplementationX(Interface):
def method(self):
pass
@injector.params(param=ImplementationX)
def somefunc(param: Interface)
param.method()
... |
It does imply that a single type has a single implementation.
There is no need to configure a binding of Take a look at this case: @injector.autoparams()
def somefunc(service: MyService) You already specified that you need
@injector.params(param=ImplementationX)
def somefunc(param: Interface) That's exactly not an implementation but another type: @injector.autoparam()
def somefunc(param: InterfaceX) And that's the idea. Just use the types to specify the whole application as a typed object graph. |
Yes, but it needs to be able to know how to instantiate it, not all constructors won't take params.
Aren't both of these contradictory ? It's theoretically a type yes, but it's used as in implementation (I forgot the @AbstractMethod) |
Ok, I understand that. However, what happens when the type needs to be polymorphic, and i need to use different implementation of it based on specific context ? Meaning, if i have this application like this How can implementations |
Simple example: class Cache:
pass
class MemCache(Cache):
pass
class RedisCache(Cache):
pass
# Later
class UserService:
cache = inject.attr(Cache)
class MailService:
cache = inject.attr(RedisCache) # not named cache "redis"
# Bindings
def configure(binder):
binder.bind(Cache, MemCache()) |
I think the issue title says it all, but one issue i faced a lot is registering 2 or more different implementations of the same interface.
This can turn out to be useful for example when introducing abstractions in the form of chains of responsibility.
Just like middlewares work for example in web frameworks, you have multiple middlewares and then we iterate on them and each one handle the request per the same interface.
Also, it should be possible to make
named
registrations of instances of the same interface, so that when you need a particular instance that you define based on some key, you can get it from the container.This is possible in frameworks like Autofac or SimpleInjector.
The text was updated successfully, but these errors were encountered: