What is the maximum number of DI registrations in an EK9 application block?

← DI Validation · Ref: Q892

An application block can have at most 12 registrations. More than 12 triggers E11042, indicating the application is trying to be a monolith.

WHY TWELVE

Research in component-based software engineering shows that systems with focused, modular composition are more maintainable. A large registration block often means the application mixes unrelated concerns.

SPLIT INTO SUB-APPLICATIONS

  defines application
    InfrastructureApp
      register DbService() as AbstractDb
      register CacheService() as AbstractCache
  defines application
    BusinessApp with application of InfrastructureApp
      register UserService() as AbstractUser
      register OrderService() as AbstractOrder

USE COMPOSITION

The 'with application of' clause composes smaller applications. Each sub-application has focused responsibilities, and the combined application inherits all registrations.

See Q667 for abstract injection. See Q798 for missing/duplicate registrations. See Q324 for DI basics.

Example

defines module qa.divalidation.applicationregistrations

  defines component

    Api01 as abstract
      work01() as abstract
        <- rtn as String?
      default operator ?
    Svc01 extends Api01
      override work01()
        <- rtn <- "s01"
      default operator ?

    Api02 as abstract
      work02() as abstract
        <- rtn as String?
      default operator ?
    Svc02 extends Api02
      override work02()
        <- rtn <- "s02"
      default operator ?

    Api03 as abstract
      work03() as abstract
        <- rtn as String?
      default operator ?
    Svc03 extends Api03
      override work03()
        <- rtn <- "s03"
      default operator ?

    Api04 as abstract
      work04() as abstract
        <- rtn as String?
      default operator ?
    Svc04 extends Api04
      override work04()
        <- rtn <- "s04"
      default operator ?

    Api05 as abstract
      work05() as abstract
        <- rtn as String?
      default operator ?
    Svc05 extends Api05
      override work05()
        <- rtn <- "s05"
      default operator ?

    Api06 as abstract
      work06() as abstract
        <- rtn as String?
      default operator ?
    Svc06 extends Api06
      override work06()
        <- rtn <- "s06"
      default operator ?

    Api07 as abstract
      work07() as abstract
        <- rtn as String?
      default operator ?
    Svc07 extends Api07
      override work07()
        <- rtn <- "s07"
      default operator ?

    Api08 as abstract
      work08() as abstract
        <- rtn as String?
      default operator ?
    Svc08 extends Api08
      override work08()
        <- rtn <- "s08"
      default operator ?

    Api09 as abstract
      work09() as abstract
        <- rtn as String?
      default operator ?
    Svc09 extends Api09
      override work09()
        <- rtn <- "s09"
      default operator ?

    Api10 as abstract
      work10() as abstract
        <- rtn as String?
      default operator ?
    Svc10 extends Api10
      override work10()
        <- rtn <- "s10"
      default operator ?

    Api11 as abstract
      work11() as abstract
        <- rtn as String?
      default operator ?
    Svc11 extends Api11
      override work11()
        <- rtn <- "s11"
      default operator ?

    Api12 as abstract
      work12() as abstract
        <- rtn as String?
      default operator ?
    Svc12 extends Api12
      override work12()
        <- rtn <- "s12"
      default operator ?

    Api13 as abstract
      work13() as abstract
        <- rtn as String?
      default operator ?
    Svc13 extends Api13
      override work13()
        <- rtn <- "s13"
      default operator ?

  defines application

    <?-
      Application with exactly 12 registrations. At the limit but valid.
      Adding a 13th would trigger E11042.
    -?>
    FocusedApp
      register Svc01() as Api01
      register Svc02() as Api02
      register Svc03() as Api03
      register Svc04() as Api04
      register Svc05() as Api05
      register Svc06() as Api06
      register Svc07() as Api07
      register Svc08() as Api08
      register Svc09() as Api09
      register Svc10() as Api10
      register Svc11() as Api11
      register Svc12() as Api12

  defines program

    ApplicationRegistrationsDemo() with application of FocusedApp
      stdout <- Stdout()
      svc01 as Api01!
      result <- svc01.work01()
      stdout.println(`Result: ${result}`)

Common mistakes

E11042 — An application block can have at most 12 registrations. This mutation adds a 13th, triggering E11042. Split large applications into focused sub-applications. See ek9 -h E11042 for details.

Incorrect:

      register Svc12() as Api12
      register Svc13() as Api13

Correct:

      register Svc12() as Api12
Other ways to ask this
  • What triggers E11042 EXCESSIVE_APPLICATION_REGISTRATIONS?
  • How many register statements can an application have?
  • Why does EK9 limit application registrations to twelve?

Coming from another language?

Java: Spring has no limit on beans per context. Python: no DI framework limit. Go: no DI framework limit. Rust: no standard DI. EK9: compiler enforces 12-registration limit per application block, encouraging modular composition.

Keywords: split, limit, E11042, DI, registration, composition, modular, twelve, application, monolith