On this page

Constructor, explicit, and collection DI๏ƒ

Beginner โ†’ Intermediate. Annotations, explicit targets, collections.

Annotate a constructor parameter. Melder builds the graph.

class ReportService:
    def __init__(self, database: Database) -> None:   # โ† injected
        self.database = database

book.bind(spell=Database, existence="unique")
book.bind(spell=ReportService, existence="unique")
conduit = book.conjure()

report = conduit.meld("ReportService")

When an annotation isn't specific enough โ€” two implementations of one shape, or a named binding โ€” declare the target with SpellMap as the parameter default:

class Consumer:
    def __init__(self, store=md.SpellMap(PrimaryStore)) -> None:
        self.store = store

SpellMap takes the full address: a concrete spell, a spellframe, a binding_name, or a combination. It obeys an exactly-one law โ€” a target that matches zero spells or several fails at conjure(), not at runtime.

Ask for a list and get every implementation โ€” the plugin pattern in one annotation:

class Dispatcher:
    def __init__(self, handlers: list[Handler]) -> None:   # โ† all of them
        self.handlers = handlers

book.bind(spell=EmailHandler, existence="unique",
          spellframe=Handler, binding_name="email")
book.bind(spell=SmsHandler, existence="unique",
          spellframe=Handler, binding_name="sms")

Runnable examples๏ƒ

All intermediate examples ยท Level contents ยท Full contents

Canonical page source