python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Q: Is it possible to use DependenciesContainer when defining a provider_type?

Open ms-lolo opened this issue 4 years ago • 3 comments

I'm trying to define a container that only provides instances that extend Foo, however, some of these instances depend on things provided by other containers. Is this possible and what would the best approach be? Here's a sample mostly taken from multiple parts of your docs:

class MainContainer(DeclarativeContainer):
    some_client = Singleton(SomeClient)

class SpecificProvider(Singleton):
    provided_type = SpecificThing

class SpecificThingsContainer(DeclarativeContainer):
    provider_type = SpecificProvider

    # this causes an error
    # if possible, I would actually prefer to hide this from the public interface of my "things" container
    main_container = DependenciesContainer()

    # how do I define this dependency on SomeClient?
    one_thing = SpecificProvider(SpecificThing, client=main_container.some_client)

ms-lolo avatar Jan 30 '21 15:01 ms-lolo

Hi @ms-lolo ,

That's what you can do as a workaround:

class SpecificThingsContainer(DeclarativeContainer):
    provider_type = (SpecificProvider, DependenciesContainer)

    main_container = DependenciesContainer()

    one_thing = SpecificProvider(SpecificThing, client=main_container.some_client)

I guess the expected behaviour is to just have it working the way it is in your example. In that case container should ignore checking the type for Dependency and DependencyContainer providers. From the first view this sounds ok, but I need to think more to make sure it doesn't break anything.

rmk135 avatar Jan 30 '21 20:01 rmk135

Thanks for the suggestion, @rmk135. It wasn't clear that I could provide a tuple of types there. I think your example will work for me. I think maybe I have a followup request. It would be nice for me to have an API for defining the things provided by the container without having to expose the dependencies (main_container in this case). For example, I would like specific_container.providers to only return one_thing in this case because I never expect anyone to call specific_container.main_container() since it only exists to resolve dependencies in my real providers. So in a way, I would like to make some providers private or internal only.

For now, I might just call it _main_container and filter specific_container.providers to remove any provider name starting with an underscore but it would be nice not to have to parse variable names and make assumptions :)

Either way, I think I can get everything I want right now following your example and adding a little extra logic of my own so thanks again for clarifying things!

ms-lolo avatar Jan 31 '21 04:01 ms-lolo

Hi @ms-lolo , ok, sounds good. I like and understand you idea. This use case makes me think about more strict boundary between dependencies and actual container providers. I'll add a backlog item to find elegant solution for this.

rmk135 avatar Feb 02 '21 13:02 rmk135