Shared Resource¶
The resource can be used multiple times in one context. Sometimes you don’t want to build a new resource for each usages. You can share resources by shared decorator.
Sharing Resource¶
from contextlib import contextmanager
from autowire import Context, Resource
from autowire.decorators import shared
dog = Resource('dog', __name__)
walk = Resource('walk', __name__)
@dog.impl
@shared
@contextmanager
def with_dog(context):
print("Dog is entering")
try:
yield "🐶"
finally:
print("Dog leaved")
@walk.impl
@contextmanager
def with_walking(context):
with context.resolve(dog) as dog_value:
yield "Walking with {}".format(dog_value)
context = Context()
with context.resolve(walk) as message:
print(message)
with context.resolve(dog) as dog_value:
print("Feeding {}".format(dog_value))
# Output:
# Dog is entering
# Walking with 🐶
# Feeding 🐶
# Dog leaved
Since dog resource is shared resource, setup & teardown were called only once.
Globally Shared Resource¶
When you have nested contexts, the shared resource will be created for each contexts.
If you want to have only one resource per whole contexts, you can do that with
globally_shared decorator.
from contextlib import contextmanager
from autowire import Context, Resource, impl
from autowire.decorators import shared
dog = Resource('dog', __name__)
walk = Resource('walk', __name__)
@impl.implement(dog)
@globally_shared
@contextmanager
def with_dog(context):
print("Dog is entering")
try:
yield "🐶"
finally:
print("Dog leaved")
@impl.implement(walk)
@contextmanager
def with_walking(context):
with context.resolve(dog) as dog_value:
yield "Walking with {}".format(dog_value)
context = Context()
child = Context(context)
with context.resolve(walk) as message:
print(message)
with child.resolve(dog) as dog_value:
print("Feeding {}".format(dog_value))
# Output:
# Dog is entering
# Walking with 🐶
# Feeding 🐶
# Dog leaved
Since, globally shared resource can be only defined on providing context, it can’t use children context’s resources.
from contextlib import contextmanager
from autowire import Context, Resource
from autowire.decorators import shared
dog = Resource('dog', __name__)
walk = Resource('walk', __name__)
@impl.implement(walk)
@globally_shared
@contextmanager
def with_walking(context):
with context.resolve(dog) as dog_value:
yield "Walking with {}".format(dog_value)
context = Context()
child = Context(context)
# Provide dog
@impl.implement(child(dog))
@contextmanager
def with_dog(context):
yield "🐶"
# Will raise ResourceNotProvidedError
with child.resolve(walk) as message:
...