Skip to content
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

Differentiating between multiple providers #234

Open
cswartzvi opened this issue Sep 21, 2023 · 4 comments
Open

Differentiating between multiple providers #234

cswartzvi opened this issue Sep 21, 2023 · 4 comments

Comments

@cswartzvi
Copy link

cswartzvi commented Sep 21, 2023

Hi! First off, this is a fantastic library - thank you for all your efforts. If I define multiple providers for the same type and then pass both providers to the Injector, the "last" provider takes precedence (see below). While I am pretty sure this is intentional - and aligns nicely with how python handles similarly named functions - I was wondering if there was a way to a) differentiate between the providers list the multiple providers for a type or b) raise an exception if multiple providers have been defined for the same type. I would be happy to contribute a PR if you think there are any worthwhile features to be added. Thanks again!

from dataclasses import dataclass
from injector import Module, singleton, provider, Injector


@dataclass
class Output:
    value: str


class Provider01(Module):
    @singleton
    @provider
    def provide_output(self) -> Output:
        return Output("Using Provider01")


class Provider02(Module):
    @singleton
    @provider
    def provide_output(self) -> Output:
        return Output("Using Provider02")


injector = Injector([Provider01(), Provider02()])
output = injector.get(Output)
print(output.value)  # Using Provider02
@davidparsson
Copy link
Collaborator

What would you want to achieve in option a? I'm not sure it matches your use case, but I have previously used parent/child injectors to override providers.

@cswartzvi
Copy link
Author

Ah, I think I choose my words poorly in this case - my apologies. @davidparsson, your suggestion about using parent/child injectors is brilliant and I will absolutely keep that in mind when I have to, knowingly, override a provider. However, what I meant to ask in (a) was more along the lines of 'is there a way to detect that multiple providers have been bound to the same type'? I will edit the original question.

@davidparsson
Copy link
Collaborator

davidparsson commented Sep 21, 2023

Thanks for clarifying. That makes sense, but I'm not aware of any way to achieve that in a general way. It's probably possible to explicitly look for previously bound classes in the provider, but that's in no way convenient.

I think it makes sense to be able to detect that, and raising an exception is probably the most intuitive way of feedback, but it's also a breaking change that I'm not sure how to introduce.

@jstasiak, what are your thoughts here?

@jstasiak
Copy link
Collaborator

I used the "last processed module overrides whatever previous modules defined if there is an overlap" behavior in tests in the past.

That said, it seems like it'd be a good idea to at least provide an option to disallow that (by raising an exception) – using a switch in the Injector constructor, possibly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants