mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-07-06 21:33:31 +03:00
Implement sub containers wiring + add tests
This commit is contained in:
parent
a02f9c6981
commit
deae475874
|
@ -1312,14 +1312,14 @@ struct __pyx_obj_19dependency_injector_9providers_List {
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* cdef class Container(Provider): # <<<<<<<<<<<<<<
|
* cdef class Container(Provider): # <<<<<<<<<<<<<<
|
||||||
* cdef object container_cls
|
* cdef object __container_cls
|
||||||
* cdef dict overriding_providers
|
* cdef dict __overriding_providers
|
||||||
*/
|
*/
|
||||||
struct __pyx_obj_19dependency_injector_9providers_Container {
|
struct __pyx_obj_19dependency_injector_9providers_Container {
|
||||||
struct __pyx_obj_19dependency_injector_9providers_Provider __pyx_base;
|
struct __pyx_obj_19dependency_injector_9providers_Provider __pyx_base;
|
||||||
PyObject *container_cls;
|
PyObject *__pyx___container_cls;
|
||||||
PyObject *overriding_providers;
|
PyObject *__pyx___overriding_providers;
|
||||||
PyObject *container;
|
PyObject *__pyx___container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1989,8 +1989,8 @@ static struct __pyx_vtabstruct_19dependency_injector_9providers_List *__pyx_vtab
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* cdef class Container(Provider): # <<<<<<<<<<<<<<
|
* cdef class Container(Provider): # <<<<<<<<<<<<<<
|
||||||
* cdef object container_cls
|
* cdef object __container_cls
|
||||||
* cdef dict overriding_providers
|
* cdef dict __overriding_providers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct __pyx_vtabstruct_19dependency_injector_9providers_Container {
|
struct __pyx_vtabstruct_19dependency_injector_9providers_Container {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -185,9 +185,9 @@ cdef class List(Provider):
|
||||||
|
|
||||||
|
|
||||||
cdef class Container(Provider):
|
cdef class Container(Provider):
|
||||||
cdef object container_cls
|
cdef object __container_cls
|
||||||
cdef dict overriding_providers
|
cdef dict __overriding_providers
|
||||||
cdef object container
|
cdef object __container
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,8 @@ class Container(Provider):
|
||||||
def __init__(self, container_cls: Type[T], container: Optional[T] = None, **overriding_providers: Provider) -> None: ...
|
def __init__(self, container_cls: Type[T], container: Optional[T] = None, **overriding_providers: Provider) -> None: ...
|
||||||
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
||||||
def __getattr__(self, name: str) -> Provider: ...
|
def __getattr__(self, name: str) -> Provider: ...
|
||||||
|
@property
|
||||||
|
def container(self) -> T: ...
|
||||||
|
|
||||||
|
|
||||||
class Selector(Provider):
|
class Selector(Provider):
|
||||||
|
|
|
@ -2477,13 +2477,13 @@ cdef class Container(Provider):
|
||||||
|
|
||||||
def __init__(self, container_cls, container=None, **overriding_providers):
|
def __init__(self, container_cls, container=None, **overriding_providers):
|
||||||
"""Initialize provider."""
|
"""Initialize provider."""
|
||||||
self.container_cls = container_cls
|
self.__container_cls = container_cls
|
||||||
self.overriding_providers = overriding_providers
|
self.__overriding_providers = overriding_providers
|
||||||
|
|
||||||
if container is None:
|
if container is None:
|
||||||
container = container_cls()
|
container = container_cls()
|
||||||
container.override_providers(**overriding_providers)
|
container.override_providers(**overriding_providers)
|
||||||
self.container = container
|
self.__container = container
|
||||||
|
|
||||||
super(Container, self).__init__()
|
super(Container, self).__init__()
|
||||||
|
|
||||||
|
@ -2494,9 +2494,9 @@ cdef class Container(Provider):
|
||||||
return copied
|
return copied
|
||||||
|
|
||||||
copied = self.__class__(
|
copied = self.__class__(
|
||||||
self.container_cls,
|
self.__container_cls,
|
||||||
deepcopy(self.container, memo),
|
deepcopy(self.__container, memo),
|
||||||
**deepcopy(self.overriding_providers, memo),
|
**deepcopy(self.__overriding_providers, memo),
|
||||||
)
|
)
|
||||||
|
|
||||||
return copied
|
return copied
|
||||||
|
@ -2508,7 +2508,11 @@ cdef class Container(Provider):
|
||||||
'\'{cls}\' object has no attribute '
|
'\'{cls}\' object has no attribute '
|
||||||
'\'{attribute_name}\''.format(cls=self.__class__.__name__,
|
'\'{attribute_name}\''.format(cls=self.__class__.__name__,
|
||||||
attribute_name=name))
|
attribute_name=name))
|
||||||
return getattr(self.container, name)
|
return getattr(self.__container, name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def container(self):
|
||||||
|
return self.__container
|
||||||
|
|
||||||
def override(self, provider):
|
def override(self, provider):
|
||||||
"""Override provider with another provider."""
|
"""Override provider with another provider."""
|
||||||
|
@ -2516,7 +2520,7 @@ cdef class Container(Provider):
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
"""Return single instance."""
|
"""Return single instance."""
|
||||||
return self.container
|
return self.__container
|
||||||
|
|
||||||
|
|
||||||
cdef class Selector(Provider):
|
cdef class Selector(Provider):
|
||||||
|
|
|
@ -25,7 +25,10 @@ class ProvidersMap:
|
||||||
|
|
||||||
def __init__(self, container):
|
def __init__(self, container):
|
||||||
self._container = container
|
self._container = container
|
||||||
self._map = self._create_providers_map(container)
|
self._map = self._create_providers_map(
|
||||||
|
current_providers=container.providers,
|
||||||
|
original_providers=container.declarative_parent.providers,
|
||||||
|
)
|
||||||
|
|
||||||
def resolve_provider(self, provider: providers.Provider) -> providers.Provider:
|
def resolve_provider(self, provider: providers.Provider) -> providers.Provider:
|
||||||
if isinstance(provider, providers.Delegate):
|
if isinstance(provider, providers.Delegate):
|
||||||
|
@ -105,18 +108,20 @@ class ProvidersMap:
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_providers_map(
|
def _create_providers_map(
|
||||||
cls,
|
cls,
|
||||||
container: AnyContainer,
|
current_providers: Dict[str, providers.Provider],
|
||||||
|
original_providers: Dict[str, providers.Provider],
|
||||||
) -> Dict[providers.Provider, providers.Provider]:
|
) -> Dict[providers.Provider, providers.Provider]:
|
||||||
current_providers = container.providers
|
|
||||||
original_providers = container.declarative_parent.providers
|
|
||||||
|
|
||||||
providers_map = {}
|
providers_map = {}
|
||||||
for provider_name, current_provider in current_providers.items():
|
for provider_name, current_provider in current_providers.items():
|
||||||
original_provider = original_providers[provider_name]
|
original_provider = original_providers[provider_name]
|
||||||
providers_map[original_provider] = current_provider
|
providers_map[original_provider] = current_provider
|
||||||
|
|
||||||
if isinstance(current_provider, providers.Container):
|
if isinstance(current_provider, providers.Container) \
|
||||||
subcontainer_map = cls._create_providers_map(current_provider.container)
|
and isinstance(original_provider, providers.Container):
|
||||||
|
subcontainer_map = cls._create_providers_map(
|
||||||
|
current_providers=current_provider.container.providers,
|
||||||
|
original_providers=original_provider.container.providers,
|
||||||
|
)
|
||||||
providers_map.update(subcontainer_map)
|
providers_map.update(subcontainer_map)
|
||||||
|
|
||||||
return providers_map
|
return providers_map
|
||||||
|
|
|
@ -3,8 +3,15 @@ from dependency_injector import containers, providers
|
||||||
from .service import Service
|
from .service import Service
|
||||||
|
|
||||||
|
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
int_object = providers.Object(1)
|
||||||
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration()
|
||||||
|
|
||||||
service = providers.Factory(Service)
|
service = providers.Factory(Service)
|
||||||
|
|
||||||
|
sub = providers.Container(SubContainer)
|
||||||
|
|
|
@ -39,3 +39,7 @@ def test_provide_provider(service_provider: Callable[..., Service] = Provider[Co
|
||||||
|
|
||||||
def test_provided_instance(some_value: int = Provide[Container.service.provided.foo['bar'].call()]):
|
def test_provided_instance(some_value: int = Provide[Container.service.provided.foo['bar'].call()]):
|
||||||
return some_value
|
return some_value
|
||||||
|
|
||||||
|
|
||||||
|
def test_subcontainer_provider(some_value: int = Provide[Container.sub.int_object]):
|
||||||
|
return some_value
|
||||||
|
|
|
@ -72,3 +72,7 @@ class WiringTest(unittest.TestCase):
|
||||||
with self.container.service.override(TestService()):
|
with self.container.service.override(TestService()):
|
||||||
some_value = module.test_provided_instance()
|
some_value = module.test_provided_instance()
|
||||||
self.assertEqual(some_value, 10)
|
self.assertEqual(some_value, 10)
|
||||||
|
|
||||||
|
def test_subcontainer(self):
|
||||||
|
some_value = module.test_subcontainer_provider()
|
||||||
|
self.assertEqual(some_value, 1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user