Skip to main content
Version: v0.10

Injection Scopes

This document explains the three dependency injection (DI) scopes used across the Identity Development Kit (IDK) core libraries and the solutions that build on top of the SDK:

  • App Scope
  • Context Scope
  • Session Scope

These scopes are implemented using Kotlin Inject + Anvil-style scoping. You will see types such as AppScope, UserContextScope, and SessionScope in the codebase.

Scope hierarchy and access rules

The scopes form a strict parent→child hierarchy:

  • App Scope (root, longest-lived)
  • Context Scope (per-tenant/principal)
  • Session Scope (per-session)

Access rules:

  • App Scope cannot access instances from Context or Session scopes. There is no “reach down” into child scopes.
  • Context Scope can access App Scope.
  • Session Scope can access both Context Scope and App Scope.

This arrangement lets shorter‑lived work reuse longer‑lived services while preserving isolation toward the bottom of the hierarchy.

App Scope

  • Lifetime: Application lifetime (process or app lifecycle).
  • Purpose: Hosts global, cross-tenant services and singletons.
  • Access: Has no access to Context or Session scoped objects (by design). Lower scopes may depend on App-scoped services.
  • Notes: Often represented via AppScope (from software.amazon.lastmile.kotlin.inject.anvil.AppScope).

User context Scope

  • Type: UserContextScope
  • Lifetime: Created early in the request/user flow and tied to a specific tenant and principal combination.
  • Purpose: Holds tenant- and principal-aware services that should be isolated per (tenant, principal).
  • Typical creation points:
  • Backend: Early request interception (e.g., middleware/interceptor) before passing control to session logic.
  • Frontend/mobile: During or immediately after authentication.
  • Annotations: Use @SingleIn(UserContextScope::class) for bindings that must be singletons within a given context.
  • Access: Can access App Scope; cannot reach down into Session Scope.

About tenant and principal:

  • “Tenant” and “principal” are generic concepts in the IDK. We provide some interfaces and example implementations, but your application/back end/front end defines how to determine the current tenant and principal.
  • The context scope is where these values are bound for the lifetime of that context.

Isolation:

  • Objects in a context scope are contained to that scope instance. They cannot observe or mutate state in other tenants/principals.

Session Scope

  • Type: SessionScope
  • Lifetime: Shortest-lived; created beneath a specific Context Scope.
  • Purpose: Encapsulates per-session state and services (e.g., logging, per-session coroutines).
  • Input: This is where the session is initialized and where tenant and principal (coming from the active Context Scope) are effectively the inputs for the session’s runtime.
  • Access: Can access Context Scope and App Scope.
  • Annotations: Use @SingleIn(SessionScope::class) for bindings that must be singletons within a given session.

Isolation:

  • Objects in a session scope are contained to that session instance. They cannot reach across different sessions, tenants, or principals.

Lifecycle and cleanup

  • Each scope owns its set of instances. When a scope is no longer referenced/used, it is cleaned up, including its resources (e.g., child coroutine scopes created via CoroutineScopeScoped).
  • The codebase provides managers to help with scope lifecycle, for example:
  • Context: UserContextManager, UserContextComponent and UserContextScope
  • Session: SessionContextManager, SessionComponent and SessionScope

Working with the IDK and SDK

  • The IDK and solutions built on the SDK assume that these scopes are used as designed. This is reflected in APIs that expect a context and/or session to be active.
  • While it may be technically possible to operate without the provided DI setup, we do not recommend it and it is not tested.

Quick reference

  • App Scope
    • Root scope
    • No access to lower scopes
    • Reused by Context/Session
  • Context Scope (UserContextScope)
    • Per-tenant/principal
    • Access to App Scope
    • Isolated across tenants/principals
  • Session Scope (SessionScope)
    • Per-session
    • Access to Context and App Scopes
    • Isolated across sessions
  • Context
    • sure.di.context.UserContextScope
    • sure.di.context.UserContextComponent
    • sure.di.context.UserContextManager
    • sure.di.context.UserContext
  • Session
    • sure.di.session.SessionScope
    • sure.di.session.SessionComponent
    • sure.di.session.SessionContextManager
    • sure.di.session.SessionContext

For more details, explore the interfaces and documentation comments within the codebase under libraries/core/api/public/src/commonMain/kotlin/sure/di/.