Decorators, Simple Case
Note
Decorators depend on the venusian
package being installed.
Our previous example didn’t do Dependency Injection (DI) which makes it pretty boring. But it saved us from writing a factory function. Let’s rewrite it to see how decorators can also save us the register_dataclass
registration step. Still no DI.
As before, we have an application with a registry. Let’s add a method that looks for our wired.dataclasses
decorators, using venusian
:
# app.py
from dataclasses import dataclass, field
from venusian import Scanner
from wired import ServiceRegistry
from . import models
@dataclass
class App:
registry: ServiceRegistry = field(default_factory=ServiceRegistry)
def scan(self):
# Look for decorators
scanner = Scanner(registry=self.registry)
scanner.scan(models)
Our Greeter
dataclass can now register itself as a wired
factory, using a decorator:
# models.py
from dataclasses import dataclass
from wired.dataclasses import factory
@factory()
@dataclass
class Greeter:
name: str = 'Mary'
def __call__(self, customer):
return f'Hello {customer} my name is {self.name}'
We no longer need the call to the register_dataclass
, which needed the registry and the target class.
The decorator knows the registry, knows the class being decorated, and can call register_dataclass
. Simple!
Our request processing is exactly the same as the previous step:
# request.py
from .models import Greeter
def process_request(registry):
# Each request gets its own container
container = registry.create_container()
# Do the work unique to this request and return result
greeter: Greeter = container.get(Greeter)
greeting = greeter('Larry')
return greeting
Putting it all together: make an app, scan for decorators, and process requests:
# Application starts up
app = App()
app.scan()
# Later, a request comes in
result = process_request(app.registry)
assert 'Hello Larry my name is Mary' == result