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

← Dependency Injection · Ref: Q961

An application block can have at most 12 registrations. Exceeding 12 triggers E11042, indicating the application is becoming a monolith.

WHY TWELVE

Large composition roots (the place where all dependencies are wired together) become hard to understand and maintain. Research in component-based software engineering shows that focused, modular composition is more maintainable.

THE FIX

Split into sub-applications using 'with application of':

  defines application
    InfrastructureApp
      register DbService() as AbstractDb
  defines application
    BusinessApp with application of InfrastructureApp
      register OrderService() as AbstractOrder

THIS EXAMPLE

The PlatformApp has exactly 11 registrations, safely under the limit of 12. The typicalError mutation adds 2 more registrations to reach 13, triggering E11042.

See Q892 for application registration limits. See Q227 for DI overview.

Example

defines module qa.di.excessivemethodinjection

  defines component

    Contract01 as abstract
      action01() as abstract
        <- rtn as String?
      default operator ?
    Impl01 extends Contract01
      override action01()
        <- rtn <- "c01"
      default operator ?

    Contract02 as abstract
      action02() as abstract
        <- rtn as String?
      default operator ?
    Impl02 extends Contract02
      override action02()
        <- rtn <- "c02"
      default operator ?

    Contract03 as abstract
      action03() as abstract
        <- rtn as String?
      default operator ?
    Impl03 extends Contract03
      override action03()
        <- rtn <- "c03"
      default operator ?

    Contract04 as abstract
      action04() as abstract
        <- rtn as String?
      default operator ?
    Impl04 extends Contract04
      override action04()
        <- rtn <- "c04"
      default operator ?

    Contract05 as abstract
      action05() as abstract
        <- rtn as String?
      default operator ?
    Impl05 extends Contract05
      override action05()
        <- rtn <- "c05"
      default operator ?

    Contract06 as abstract
      action06() as abstract
        <- rtn as String?
      default operator ?
    Impl06 extends Contract06
      override action06()
        <- rtn <- "c06"
      default operator ?

    Contract07 as abstract
      action07() as abstract
        <- rtn as String?
      default operator ?
    Impl07 extends Contract07
      override action07()
        <- rtn <- "c07"
      default operator ?

    Contract08 as abstract
      action08() as abstract
        <- rtn as String?
      default operator ?
    Impl08 extends Contract08
      override action08()
        <- rtn <- "c08"
      default operator ?

    Contract09 as abstract
      action09() as abstract
        <- rtn as String?
      default operator ?
    Impl09 extends Contract09
      override action09()
        <- rtn <- "c09"
      default operator ?

    Contract10 as abstract
      action10() as abstract
        <- rtn as String?
      default operator ?
    Impl10 extends Contract10
      override action10()
        <- rtn <- "c10"
      default operator ?

    Contract11 as abstract
      action11() as abstract
        <- rtn as String?
      default operator ?
    Impl11 extends Contract11
      override action11()
        <- rtn <- "c11"
      default operator ?

    Contract12 as abstract
      action12() as abstract
        <- rtn as String?
      default operator ?
    Impl12 extends Contract12
      override action12()
        <- rtn <- "c12"
      default operator ?

    Contract13 as abstract
      action13() as abstract
        <- rtn as String?
      default operator ?
    Impl13 extends Contract13
      override action13()
        <- rtn <- "c13"
      default operator ?

  defines application

    <?-
      PlatformApp has 11 registrations, under the limit of 12.
      Adding 2 more would trigger E11042.
    -?>
    PlatformApp
      register Impl01() as Contract01
      register Impl02() as Contract02
      register Impl03() as Contract03
      register Impl04() as Contract04
      register Impl05() as Contract05
      register Impl06() as Contract06
      register Impl07() as Contract07
      register Impl08() as Contract08
      register Impl09() as Contract09
      register Impl10() as Contract10
      register Impl11() as Contract11

  defines program

    ExcessiveMethodInjectionDemo() with application of PlatformApp
      stdout <- Stdout()
      svc as Contract01!
      result <- svc.action01()
      stdout.println(`Result: ${result}`)
      stdout.println("PlatformApp has 11 registrations (under limit of 12)")

Common mistakes

E11042 — Adding 2 more registrations brings the total to 13, exceeding the limit of 12. Split into focused sub-applications. See ek9 -h E11042 for details.

Incorrect:

      register Impl10() as Contract10
      register Impl11() as Contract11
      register Impl12() as Contract12
      register Impl13() as Contract13

Correct:

      register Impl10() as Contract10
      register Impl11() as Contract11
Other ways to ask this
  • What triggers E11042 EXCESSIVE_APPLICATION_REGISTRATIONS?
  • Why does EK9 limit application registrations?
  • How do I split a large application block?

Coming from another language?

Java Spring: unlimited beans per context. Python: no DI limits. Go Wire: no limits. Rust: no standard DI. EK9: compiler enforces 12-registration limit per application block.

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