mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-21 14:05:11 +03:00
Add support of multiple scopes for providers.Scoped
This commit is contained in:
parent
fa113af977
commit
7ab731eacc
|
@ -34,44 +34,13 @@ class Catalog(AbstractCatalog):
|
||||||
""":type: (objects.Provider) -> ObjectA"""
|
""":type: (objects.Provider) -> ObjectA"""
|
||||||
|
|
||||||
|
|
||||||
# Making scope using `with` statement.
|
|
||||||
with Catalog.object_a as object_a_provider:
|
|
||||||
object_a1 = object_a_provider()
|
|
||||||
object_a2 = object_a_provider()
|
|
||||||
|
|
||||||
assert object_a1 is object_a2
|
|
||||||
assert object_a1.db is object_a2.db
|
|
||||||
|
|
||||||
# Making another one scope using `with` statement.
|
|
||||||
with Catalog.object_a as object_a_provider:
|
|
||||||
object_a3 = object_a_provider()
|
|
||||||
object_a4 = object_a_provider()
|
|
||||||
|
|
||||||
assert object_a3 is object_a4
|
|
||||||
assert object_a3.db is object_a4.db
|
|
||||||
|
|
||||||
assert (object_a1 is not object_a3) and \
|
|
||||||
(object_a1 is not object_a4)
|
|
||||||
assert (object_a2 is not object_a3) and \
|
|
||||||
(object_a2 is not object_a4)
|
|
||||||
|
|
||||||
|
|
||||||
# Making one more scope using provider methods.
|
# Making one more scope using provider methods.
|
||||||
Catalog.object_a.in_scope()
|
Catalog.object_a.in_scope('request')
|
||||||
|
|
||||||
object_a5 = Catalog.object_a()
|
object_a1 = Catalog.object_a()
|
||||||
object_a6 = Catalog.object_a()
|
object_a2 = Catalog.object_a()
|
||||||
|
|
||||||
Catalog.object_a.out_of_scope()
|
Catalog.object_a.out_of_scope('request')
|
||||||
|
|
||||||
assert object_a5 is object_a6
|
assert object_a1 is object_a2
|
||||||
assert object_a5.db is object_a6.db
|
assert object_a1.db is object_a2.db
|
||||||
|
|
||||||
assert (object_a1 is not object_a3) and \
|
|
||||||
(object_a1 is not object_a4) and \
|
|
||||||
(object_a1 is not object_a5) and \
|
|
||||||
(object_a1 is not object_a6)
|
|
||||||
assert (object_a2 is not object_a3) and \
|
|
||||||
(object_a2 is not object_a4) and \
|
|
||||||
(object_a2 is not object_a5) and \
|
|
||||||
(object_a2 is not object_a6)
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ class Singleton(NewInstance):
|
||||||
self.instance = None
|
self.instance = None
|
||||||
|
|
||||||
|
|
||||||
class Scoped(Singleton):
|
class Scoped(NewInstance):
|
||||||
|
|
||||||
"""Scoped provider.
|
"""Scoped provider.
|
||||||
|
|
||||||
|
@ -142,38 +142,38 @@ class Scoped(Singleton):
|
||||||
on every call.
|
on every call.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('is_in_scope',)
|
__slots__ = ('current_scope', 'scopes_to_instances')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
self.is_in_scope = None
|
self.current_scope = None
|
||||||
|
self.scopes_to_instances = dict()
|
||||||
super(Scoped, self).__init__(*args, **kwargs)
|
super(Scoped, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def in_scope(self):
|
def in_scope(self, scope):
|
||||||
"""Set provider in "in scope" state."""
|
"""Set provider in "in scope" state."""
|
||||||
self.is_in_scope = True
|
self.current_scope = scope
|
||||||
self.reset()
|
|
||||||
|
|
||||||
def out_of_scope(self):
|
def out_of_scope(self, scope):
|
||||||
"""Set provider in "out of scope" state."""
|
"""Set provider in "out of scope" state."""
|
||||||
self.is_in_scope = False
|
self.current_scope = None
|
||||||
self.reset()
|
try:
|
||||||
|
del self.scopes_to_instances[scope]
|
||||||
|
except KeyError:
|
||||||
|
raise Error('Trying to move out of undefined scope '
|
||||||
|
'"{}"'.format(scope))
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
"""Return provided instance."""
|
"""Return provided instance."""
|
||||||
if not self.is_in_scope:
|
if not self.current_scope:
|
||||||
raise Error('Trying to provide {} '.format(self.provides) +
|
raise Error('Trying to provide {} '.format(self.provides) +
|
||||||
'while provider is not in scope')
|
'while provider is not in scope')
|
||||||
return super(Scoped, self).__call__(*args, **kwargs)
|
try:
|
||||||
|
instance = self.scopes_to_instances[self.current_scope]
|
||||||
def __enter__(self):
|
except KeyError:
|
||||||
"""Make provider to be in scope."""
|
instance = super(Scoped, self).__call__(*args, **kwargs)
|
||||||
self.in_scope()
|
self.scopes_to_instances[self.current_scope] = instance
|
||||||
return self
|
return instance
|
||||||
|
|
||||||
def __exit__(self, *_):
|
|
||||||
"""Make provider to be out of scope."""
|
|
||||||
self.out_of_scope()
|
|
||||||
|
|
||||||
|
|
||||||
class ExternalDependency(Provider):
|
class ExternalDependency(Provider):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user