mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-16 19:40:59 +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"""
|
||||
|
||||
|
||||
# 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.
|
||||
Catalog.object_a.in_scope()
|
||||
Catalog.object_a.in_scope('request')
|
||||
|
||||
object_a5 = Catalog.object_a()
|
||||
object_a6 = Catalog.object_a()
|
||||
object_a1 = 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_a5.db is object_a6.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)
|
||||
assert object_a1 is object_a2
|
||||
assert object_a1.db is object_a2.db
|
||||
|
|
|
@ -134,7 +134,7 @@ class Singleton(NewInstance):
|
|||
self.instance = None
|
||||
|
||||
|
||||
class Scoped(Singleton):
|
||||
class Scoped(NewInstance):
|
||||
|
||||
"""Scoped provider.
|
||||
|
||||
|
@ -142,38 +142,38 @@ class Scoped(Singleton):
|
|||
on every call.
|
||||
"""
|
||||
|
||||
__slots__ = ('is_in_scope',)
|
||||
__slots__ = ('current_scope', 'scopes_to_instances')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initializer."""
|
||||
self.is_in_scope = None
|
||||
self.current_scope = None
|
||||
self.scopes_to_instances = dict()
|
||||
super(Scoped, self).__init__(*args, **kwargs)
|
||||
|
||||
def in_scope(self):
|
||||
def in_scope(self, scope):
|
||||
"""Set provider in "in scope" state."""
|
||||
self.is_in_scope = True
|
||||
self.reset()
|
||||
self.current_scope = scope
|
||||
|
||||
def out_of_scope(self):
|
||||
def out_of_scope(self, scope):
|
||||
"""Set provider in "out of scope" state."""
|
||||
self.is_in_scope = False
|
||||
self.reset()
|
||||
self.current_scope = None
|
||||
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):
|
||||
"""Return provided instance."""
|
||||
if not self.is_in_scope:
|
||||
if not self.current_scope:
|
||||
raise Error('Trying to provide {} '.format(self.provides) +
|
||||
'while provider is not in scope')
|
||||
return super(Scoped, self).__call__(*args, **kwargs)
|
||||
|
||||
def __enter__(self):
|
||||
"""Make provider to be in scope."""
|
||||
self.in_scope()
|
||||
return self
|
||||
|
||||
def __exit__(self, *_):
|
||||
"""Make provider to be out of scope."""
|
||||
self.out_of_scope()
|
||||
try:
|
||||
instance = self.scopes_to_instances[self.current_scope]
|
||||
except KeyError:
|
||||
instance = super(Scoped, self).__call__(*args, **kwargs)
|
||||
self.scopes_to_instances[self.current_scope] = instance
|
||||
return instance
|
||||
|
||||
|
||||
class ExternalDependency(Provider):
|
||||
|
|
Loading…
Reference in New Issue
Block a user