What happens when a component is injected but not registered?

← DI Validation · Ref: Q673

When a program injects a component type that has no matching registration in the linked application, the compiler raises E08210. Every injection point must have a corresponding 'register' declaration.

MISSING REGISTRATION

If program injects 'service as Logger!' but the application has no 'register ... as Logger', the compiler detects this at compile time.

COMPLETENESS VALIDATION

The compiler validates that ALL injection points in the program (and its transitive component dependencies) can be satisfied by the application's registrations.

FIXING

1. Add the missing registration to the application
2. Register a concrete implementation 'as' the abstract type
3. Ensure ALL transitive dependencies are registered

TRANSITIVE DEPENDENCIES

If ComponentA injects ComponentB, and ComponentB injects ComponentC, then the application must register implementations for BOTH B and C.

See Q672 for program-application linking. See Q674 for duplicate registration. See Q671 for circular dependencies.

Example

defines module qa.divalidation.missingreg

  defines component

    <?-
      Abstract authentication service.
    -?>
    AuthService as abstract

      authenticate() as abstract
        -> credentials as String
        <- authenticated as Boolean?

      default operator ?

    <?-
      Token-based authentication implementation.
    -?>
    TokenAuth extends AuthService

      override authenticate()
        -> credentials as String
        <- authenticated as Boolean: true

      default operator ?

    <?-
      Abstract session manager.
    -?>
    SessionManager as abstract

      createSession() as abstract
        -> userName as String
        <- sessionToken as String?

      default operator ?

    <?-
      In-memory session manager implementation.
    -?>
    InMemorySessionManager extends SessionManager

      override createSession()
        -> userName as String
        <- sessionToken as String: ""

        sessionToken: "session-" + userName

      default operator ?

  defines application

    <?-
      Complete application: registers BOTH components.
      Every injection point in the program must be satisfied.
    -?>
    CompleteApp
      register TokenAuth() as AuthService
      register InMemorySessionManager() as SessionManager

  defines program

    MissingRegistrationDemo() with application of CompleteApp
      stdout <- Stdout()

      authService as AuthService!
      sessionMgr as SessionManager!

      isValid <- authService.authenticate("admin:secret")
      stdout.println(`Authenticated: ${isValid}`)

      token <- sessionMgr.createSession("admin")
      stdout.println(`Session: ${token}`)

Common mistakes

E50010 — Every injection point in the program and its transitive dependencies must have a matching registration in the linked application. If the program injects SessionManager but the application only registers AuthService, the compiler cannot resolve the SessionManager injection point. See ek9 -h E50010 for details.

Incorrect:

IncompleteApp
      register TokenAuth() as AuthService

Correct:

CompleteApp
      register TokenAuth() as AuthService
      register InMemorySessionManager() as SessionManager
Other ways to ask this
  • What is E08210 missing registration for injected component?
  • How do I fix unresolved injection errors?
  • Why does my program fail with missing component registration?

Coming from another language?

Java: Spring NoSuchBeanDefinitionException at runtime. Python: runtime ImportError. Go: compile-time (manual wiring). Rust: compile-time (no DI). EK9: compile-time E08210 validates all injection points have registrations.

Keywords: component, validate, compile-time, missing, injection, application, registration, E08210, DI, inject