Which constructs support component injection?

← DI Validation · Ref: Q668

Only specific EK9 constructs support component injection with the '!' suffix (E08160). Injection is available in components, services, and programs linked to applications.

INJECTABLE CONTEXTS

  defines component — field injection
  defines service — field injection
  defines programwith application of AppName

NON-INJECTABLE CONTEXTS

  defines function — no DI container access
  defines record — no DI container access
  defines class — no DI container access (use component instead)

PROGRAM REQUIREMENT

Programs must declare 'with application of AppName' to enable injection. Without this linkage, the compiler cannot resolve which implementations to inject (E08220).

See Q111 for component basics. See Q666 for pure context. See Q667 for abstract injection. See Q672 for program-application linking.

Example

defines module qa.divalidation.injectablecontexts

  defines component

    <?-
      Abstract notification service contract.
    -?>
    NotificationService as abstract

      sendNotification() as abstract
        -> recipient as String

      default operator ?

    <?-
      Email-based notification implementation.
    -?>
    EmailNotifier extends NotificationService

      override sendNotification()
        -> recipient as String
        stdout <- Stdout()
        stdout.println(`Email sent to ${recipient}`)

      default operator ?

  defines application

    OrderApp
      register EmailNotifier() as NotificationService

  defines program

    <?-
      Program with injection: 'with application of' enables DI.
      This is the correct injectable context for programs.
    -?>
    InjectableContextDemo() with application of OrderApp
      stdout <- Stdout()

      notifier as NotificationService!
      notifier.sendNotification("demo-recipient")

      stdout.println("Injection works in programs linked to applications")
      stdout.println("Components and services also support injection")

Common mistakes

E50001 — Component injection with '!' is only valid in components, services, and programs linked to an application. Functions, records, and classes do not have access to the DI container. Programs must use 'with application of' to enable injection. See ek9 -h E50001 for details.

Incorrect:

NonInjectableDemo()
      notifier as NotificationService!

Correct:

InjectableContextDemo() with application of OrderApp
      stdout <- Stdout()

      notifier as NotificationService!
Other ways to ask this
  • What is E08160 injection not possible in context?
  • Can I inject in functions or records?
  • Where can I use the ! injection suffix?

Coming from another language?

Java: Spring @Autowired works in any managed bean. Python: inject anywhere with frameworks. Go: manual wiring. Rust: no DI framework. EK9: injection limited to components, services, and programs for architectural clarity.

Keywords: validate, injection, E08160, program, registration, component, DI, service, context, inject, constant