Inject a Logger dependency into a component's field using the ! suffix.

← Dependency Injection · Ref: Q1112

Declare injection fields with the ! suffix:

  MessageService is Service
    logger as Logger!

The compiler validates at compile time that a matching registration exists. Only abstract component types can be injection targets.

See Q1110 for register/inject basics. See Q227 for compile-time validation.

Example

defines module qa.di.fieldinjection

  defines component

    Logger as abstract
      log() as abstract
        -> message as String
        <- output as String?
      default operator ?

    ConsoleLogger is Logger
      override log()
        -> message as String
        <- output as String: `[INFO] ${message}`
      default operator ?

    Service as abstract
      send() as abstract
        -> message as String
        <- result as String?
      default operator ?

    //logger field is injected via ! suffix
    MessageService is Service
      logger as Logger!

      override send()
        -> message as String
        <- result <- String()
        result: logger.log(message)

      default operator ?

  defines application

    FieldInjectionApp
      register ConsoleLogger() as Logger
      register MessageService() as Service

  defines program

    FieldInjectionDemo() with application of FieldInjectionApp
      stdout <- Stdout()
      service as Service!
      result <- service.send("Hello from DI")
      stdout.println(result)

Common mistakes

E08150 — Injection fields must use abstract types. Inject the abstraction (Logger), not the concrete implementation (ConsoleLogger).

Incorrect:

      logger as ConsoleLogger!

Correct:

      logger as Logger!
Other ways to ask this
  • I need a MessageService component that gets its Logger from the DI container
  • In Spring I'd use @Autowired on a field. Show the EK9 field injection pattern
  • Given a service component, declare an injection field with the ! suffix
  • Wire a Logger into a MessageService component through field injection

Coming from another language?

Spring: @Autowired private Logger logger. Guice: @Inject Logger logger. EK9: logger as Logger! — the ! suffix marks injection.

Keywords: component, autowired, inject, !, dependency, field