mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-19 21:10:57 +03:00
Add working prototype for sample 1 and 3
This commit is contained in:
parent
1c433ed0ad
commit
ff3ae95482
File diff suppressed because it is too large
Load Diff
|
@ -44,7 +44,9 @@ class Container:
|
||||||
def shutdown_resources(self) -> Optional[Awaitable]: ...
|
def shutdown_resources(self) -> Optional[Awaitable]: ...
|
||||||
def apply_container_providers_overridings(self) -> None: ...
|
def apply_container_providers_overridings(self) -> None: ...
|
||||||
def reset_singletons(self) -> None: ...
|
def reset_singletons(self) -> None: ...
|
||||||
def resolve_provider_name(self, provider: Provider) -> Optional[str]: ...
|
def resolve_provider_name(self, provider: Provider) -> str: ...
|
||||||
|
@property
|
||||||
|
def parent_name(self) -> str: ...
|
||||||
@overload
|
@overload
|
||||||
def traverse(self, types: Optional[Iterable[Type[TT]]] = None) -> _Iterator[TT]: ...
|
def traverse(self, types: Optional[Iterable[Type[TT]]] = None) -> _Iterator[TT]: ...
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -113,7 +113,7 @@ class DynamicContainer(Container):
|
||||||
|
|
||||||
self.providers[name] = value
|
self.providers[name] = value
|
||||||
|
|
||||||
if isinstance(value, providers.Dependency):
|
if isinstance(value, (providers.Dependency, providers.DependenciesContainer)):
|
||||||
value.set_parent(self)
|
value.set_parent(self)
|
||||||
|
|
||||||
super(DynamicContainer, self).__setattr__(name, value)
|
super(DynamicContainer, self).__setattr__(name, value)
|
||||||
|
@ -300,6 +300,11 @@ class DynamicContainer(Container):
|
||||||
for provider in self.traverse(types=[providers.BaseSingleton]):
|
for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
provider.reset()
|
provider.reset()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_name(self):
|
||||||
|
"""Return parent name."""
|
||||||
|
return self.declarative_parent.__name__
|
||||||
|
|
||||||
def resolve_provider_name(self, provider):
|
def resolve_provider_name(self, provider):
|
||||||
"""Try to resolve provider name."""
|
"""Try to resolve provider name."""
|
||||||
# TODO: add tests
|
# TODO: add tests
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -50,6 +50,7 @@ cdef class ExternalDependency(Dependency):
|
||||||
|
|
||||||
cdef class DependenciesContainer(Object):
|
cdef class DependenciesContainer(Object):
|
||||||
cdef dict __providers
|
cdef dict __providers
|
||||||
|
cdef object __parent
|
||||||
|
|
||||||
cpdef object _override_providers(self, object container)
|
cpdef object _override_providers(self, object container)
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,12 @@ class DependenciesContainer(Object):
|
||||||
def __getattr__(self, name: str) -> Provider: ...
|
def __getattr__(self, name: str) -> Provider: ...
|
||||||
@property
|
@property
|
||||||
def providers(self) -> _Dict[str, Provider]: ...
|
def providers(self) -> _Dict[str, Provider]: ...
|
||||||
|
def resolve_provider_name(self, provider: Provider) -> str: ...
|
||||||
|
@property
|
||||||
|
def parent_name(self) -> str: ...
|
||||||
|
@property
|
||||||
|
def parent(self) -> ProviderParent: ...
|
||||||
|
def set_parent(self, parent: ProviderParent) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class Callable(Provider[T]):
|
class Callable(Provider[T]):
|
||||||
|
|
|
@ -751,12 +751,18 @@ cdef class Dependency(Provider):
|
||||||
raise Error('{0} is not an instance of {1}'.format(instance, self.instance_of))
|
raise Error('{0} is not an instance of {1}'.format(instance, self.instance_of))
|
||||||
|
|
||||||
def _raise_undefined_error(self):
|
def _raise_undefined_error(self):
|
||||||
|
error_message = 'Dependency is not defined'
|
||||||
|
|
||||||
if is_container_instance(self.parent) and self.parent.declarative_parent is not None:
|
if is_container_instance(self.parent) and self.parent.declarative_parent is not None:
|
||||||
name_in_container = self.parent.resolve_provider_name(self)
|
name_in_container = self.parent.resolve_provider_name(self)
|
||||||
name = f'{self.parent.declarative_parent.__name__}.{name_in_container}'
|
parent_name = self.parent.parent_name
|
||||||
raise Error(f'Dependency "{name}" is not defined')
|
error_message = f'Dependency "{parent_name}.{name_in_container}" is not defined'
|
||||||
|
elif isinstance(self.parent, DependenciesContainer):
|
||||||
|
name_in_container = self.parent.resolve_provider_name(self)
|
||||||
|
parent_name = self.parent.parent_name
|
||||||
|
error_message = f'Dependency "{parent_name}.{name_in_container}" is not defined'
|
||||||
|
|
||||||
raise Error('Dependency is not defined')
|
raise Error(error_message)
|
||||||
|
|
||||||
|
|
||||||
cdef class ExternalDependency(Dependency):
|
cdef class ExternalDependency(Dependency):
|
||||||
|
@ -824,6 +830,13 @@ cdef class DependenciesContainer(Object):
|
||||||
def __init__(self, **dependencies):
|
def __init__(self, **dependencies):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
self.__providers = dependencies
|
self.__providers = dependencies
|
||||||
|
|
||||||
|
for provider in dependencies.items():
|
||||||
|
if isinstance(provider, (Dependency, DependenciesContainer)):
|
||||||
|
provider.set_parent(self)
|
||||||
|
|
||||||
|
self.__parent = None
|
||||||
|
|
||||||
super(DependenciesContainer, self).__init__(None)
|
super(DependenciesContainer, self).__init__(None)
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
|
@ -835,9 +848,19 @@ cdef class DependenciesContainer(Object):
|
||||||
return copied
|
return copied
|
||||||
|
|
||||||
copied = self.__class__()
|
copied = self.__class__()
|
||||||
|
memo[id(self)] = copied
|
||||||
|
|
||||||
copied.__provides = deepcopy(self.__provides, memo)
|
copied.__provides = deepcopy(self.__provides, memo)
|
||||||
copied.__providers = deepcopy(self.__providers, memo)
|
copied.__providers = deepcopy(self.__providers, memo)
|
||||||
|
|
||||||
|
# TODO: remove duplication
|
||||||
|
copied_parent = (
|
||||||
|
deepcopy(self.__parent, memo)
|
||||||
|
if is_provider(self.parent) or is_container_instance(self.parent)
|
||||||
|
else self.parent
|
||||||
|
)
|
||||||
|
copied.set_parent(copied_parent)
|
||||||
|
|
||||||
self._copy_overridings(copied, memo)
|
self._copy_overridings(copied, memo)
|
||||||
|
|
||||||
return copied
|
return copied
|
||||||
|
@ -853,6 +876,8 @@ cdef class DependenciesContainer(Object):
|
||||||
provider = self.__providers.get(name)
|
provider = self.__providers.get(name)
|
||||||
if not provider:
|
if not provider:
|
||||||
provider = Dependency()
|
provider = Dependency()
|
||||||
|
provider.set_parent(self)
|
||||||
|
|
||||||
self.__providers[name] = provider
|
self.__providers[name] = provider
|
||||||
|
|
||||||
container = self.__call__()
|
container = self.__call__()
|
||||||
|
@ -912,6 +937,29 @@ cdef class DependenciesContainer(Object):
|
||||||
yield from self.providers.values()
|
yield from self.providers.values()
|
||||||
yield from super().related
|
yield from super().related
|
||||||
|
|
||||||
|
def resolve_provider_name(self, provider):
|
||||||
|
"""Try to resolve provider name."""
|
||||||
|
# TODO: add tests
|
||||||
|
for provider_name, container_provider in self.providers.items():
|
||||||
|
if container_provider is provider:
|
||||||
|
return provider_name
|
||||||
|
else:
|
||||||
|
raise Error(f'Can not resolve name for provider "{provider}"')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_name(self):
|
||||||
|
"""Return parent name."""
|
||||||
|
return f'{self.parent.parent_name}.{self.parent.resolve_provider_name(self)}'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent(self):
|
||||||
|
"""Return parent."""
|
||||||
|
return self.__parent
|
||||||
|
|
||||||
|
def set_parent(self, parent):
|
||||||
|
"""Set parent."""
|
||||||
|
self.__parent = parent
|
||||||
|
|
||||||
cpdef object _override_providers(self, object container):
|
cpdef object _override_providers(self, object container):
|
||||||
"""Override providers with providers from provided container."""
|
"""Override providers with providers from provided container."""
|
||||||
for name, dependency_provider in container.providers.items():
|
for name, dependency_provider in container.providers.items():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user