Simple Construction
Before looking at injection, let’s take a look at how dataclasses get registered. We’ll use a very simple example: a Greeter
that greets people, for example in a grocery store.
First, imagine we have a nice, boring Greeter
:
# models.py
from dataclasses import dataclass
@dataclass
class Greeter:
name: str = 'Mary'
def __call__(self, customer):
return f'Hello {customer} my name is {self.name}'
Since this is a wired
application, we need an application with a registry. Dataclasses are fun, let’s use them for our application:
# app.py
from dataclasses import dataclass, field
from wired import ServiceRegistry
@dataclass
class App:
registry: ServiceRegistry = field(default_factory=ServiceRegistry)
During startup, we create the app (and thus registry) and then start configuring our stuff. For example, here is a configuration step:
# configure.py
from wired import ServiceRegistry
from wired.dataclasses import register_dataclass
from .models import Greeter
def register(registry: ServiceRegistry):
register_dataclass(registry, Greeter)
If we were using wired
directly, we would have to define a factory function and register it:
# NO LONGER NEED THIS, wired.dataclasses makes a factory
def greeter_factory(container):
greeter = Greeter()
return greeter
registry.register_factory(greeter_factory, Greeter)
But with wired.dataclasses
, no factory function is needed, as wired.dataclasses makes a factory for you
The application is now finished starting up. Later on, it’s time to process a “request”. Here’s a function that can do so:
# 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
Now let’s put all these pieces together: models, application, configuration, and request processing:
# Application starts up, imports App and configure
app = App()
configure.register(app.registry)
# Later, a request comes in
result = process_request(app.registry)
assert 'Hello Larry my name is Mary' == result
This was a very simple example: the Greeter
needed nothing from its environment because the only field had a default value. Thus, the only parts of “DI” used were construction of the dataclass instance.