moonbitstack/moonapi/di does not have a README file

    Container

    pub(all) struct Container[V] {
    providers : Map[String, Provider[V]]
    overrides : Map[String, Provider[V]]
    }

    The provider registry: key -> Provider, plus a separate overrides map that shadows it. Overrides are FastAPI's app.dependency_overrides — a test swaps a real dependency (a live DB session) for a fake without touching the routes. A registered override always wins over the base provider.

    Container::clear_override

    fn[V] Container::clear_override(self : Container[V], key : String) -> Unit

    Drop the override for key (no-op if none), restoring the base provider.

    Container::clear_overrides

    fn[V] Container::clear_overrides(self : Container[V]) -> Unit

    Drop every override — the usual test teardown that returns the container to its production wiring.

    Container::erase

    fn[V] Container::erase(self : Container[V]) -> Deps

    This container with its value type erased, ready for App::depends. The providers, the per-request cache, the sub-dependency resolution and the LIFO teardown are all the container's own; erasure hides only the value.

    Container::new

    fn[V] Container::new() -> Container[V]

    An empty container.

    Container::open_scope

    fn[V] Container::open_scope(self : Container[V]) -> Scope[V]

    Open a fresh request scope over this container.

    Container::override_

    fn[V] Container::override_(self : Container[V], key : String, factory : () -> V, teardown? : (V, Error?) -> Unit) -> Container[V]

    Register a dependency override for key — FastAPI's app.dependency_overrides[dep] = fake. Takes precedence over the base provider until cleared.

    Container::provide

    fn[V] Container::provide(self : Container[V], key : String, factory : () -> V, teardown? : (V, Error?) -> Unit) -> Container[V]

    Register a base provider under key (last registration wins), returning the container so registrations can chain.

    Container::provide_using

    fn[V] Container::provide_using(self : Container[V], key : String, factory : (Scope[V]) -> V, teardown? : (V, Error?) -> Unit) -> Container[V]

    Register a base provider whose factory resolves sub-dependencies through the request scope it is handed (FastAPI's nested Depends). Otherwise like provide.

    Container::run

    Run handler inside a fresh request scope, then tear the scope down — the setup/teardown pair wrapped around a handler, exactly as a FastAPI yield dependency brackets the request. The handler resolves whatever it needs through the scope; every dependency built during the call is released (LIFO) once it returns, then the response is handed back.

    A handler that raises is released the same way, and the error reaches the teardowns before it is re-raised for the app's exception handlers to map: cleanup that only ran on the happy path would leak exactly when it matters.

    Deps

    pub struct Deps {
    open : () -> DepsScope
    }

    A container with its dependency value type erased (Container::erase builds one), so a non-generic App can hold one. Resolving through it runs a provider's factory and records its teardown exactly as Scope::get does; what it cannot do is hand the value back — which is precisely what a route-level dependency does not need, since FastAPI's dependencies=[...] discards the values it builds and keeps only their effects.

    DepsScope

    pub struct DepsScope {
    resolve : (String) -> Bool
    close : (Error?) -> Unit
    }

    One request's resolution scope over an erased container: resolve a key (false when nothing provides it), then close, handing any failure to the teardowns.

    Provider

    pub(all) struct Provider[V] {
    factory : (Scope[V]) -> V
    teardown : (V, Error?) -> Unit
    }

    A provider: a keyed factory that builds a request-scoped dependency value, with an optional teardown run after the handler (FastAPI's yield dependencies, whose post-yield body is cleanup). The factory runs at most once per request scope; the teardown receives the produced value and the error that ended the request, None when it succeeded — the exception a FastAPI yield dependency sees when it wraps its yield in a try. The factory is handed the Scope so it can resolve sub-dependencies through it — FastAPI's Depends(a) where a itself declares Depends(b).

    Provider::new

    fn[V] Provider::new(factory : () -> V, teardown? : (V, Error?) -> Unit) -> Provider[V]

    Build a leaf provider whose factory needs nothing else. teardown defaults to a no-op — the common "plain value, nothing to release" case.

    Provider::scoped

    fn[V] Provider::scoped(factory : (Scope[V]) -> V, teardown? : (V, Error?) -> Unit) -> Provider[V]

    Build a provider whose factory resolves other dependencies through the request Scope it is handed — the sub-dependency case (FastAPI's nested Depends).

    Scope

    pub struct Scope[V] {
    container : Container[V]
    cache : Map[String, V]
    building : Map[String, Bool]
    teardowns : Array[(Error?) -> Unit]
    }

    A request-scoped resolution scope. Each dependency is built at most once and its value cached for the life of the scope (FastAPI's per-request dependency cache), and each built value's teardown is recorded to run — in reverse registration order (LIFO) — when the scope closes. Open one per request, resolve dependencies through it, then close it (or use Container::run).

    Scope::close

    fn[V] Scope::close(self : Scope[V], failure? : Error) -> Unit

    Run every recorded teardown in LIFO order and clear them, so a closed scope is inert. Mirrors FastAPI unwinding yield dependencies in reverse — the last opened is torn down first. failure is the error that ended the request and is handed to every teardown, so cleanup can tell a failed request from a successful one and roll back rather than commit.

    Scope::get

    fn[V] Scope::get(self : Scope[V], key : String) -> V?

    Resolve key within this scope: return the already-built instance if the dependency was resolved earlier in the same request; otherwise run its factory once, cache the value, register its teardown, and return it. None when no provider (or override) is registered for key.

    Source Files

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io