Why can't I instantiate a program or application with a constructor call in EK9?

← Dependency Injection · Ref: Q1312

Programs and applications are not ordinary objects, so they cannot be created with a constructor call. Writing 'app <- MyApplication()' or 'prog <- MyProgram()' raises E05200 (INCOMPATIBLE_GENUS_CONSTRUCTOR): the PROGRAM, GENERAL_APPLICATION and SERVICE_APPLICATION genus types reject local constructor use.

A program is the operating-system entry point; the runtime starts it. An application is the dependency-injection blueprint; it is brought to life by a program that declares 'with application of AppName'. You never construct either by hand.

The correct pattern is to define the application with its 'register' statements, then bind a program to it with 'with application of', and let injection ('!') resolve the registered components. No constructor call is needed or allowed for the program or the application itself.

See Q231 for program-application linking. See Q672 for the 'with application of' requirement.

Example

defines module qa.di.program.app.construction

  defines component

    OrderService as abstract
      process() as abstract
        <- summary as String?

      default operator ?

    StandardOrderService is OrderService
      override process()
        <- summary as String: "order processed"

      default operator ?

  defines application

    //The application is the dependency-injection blueprint.
    //It is never constructed by hand; a program brings it to life.
    OrderApp
      register StandardOrderService() as OrderService

  defines program

    //CORRECT: bind the program to the application with 'with application of'.
    //No constructor call is made on the program or the application.
    RunDemo() with application of OrderApp
      stdout <- Stdout()

      service as OrderService!
      stdout.println(service.process())

Common mistakes

E05200 — An application (and a program) has a special genus and cannot be created with a constructor call, so 'app <- OrderApp()' triggers E05200 INCOMPATIBLE_GENUS_CONSTRUCTOR. The application is a dependency-injection blueprint, not an object you build: bind the program to it with 'with application of OrderApp' and let '!' inject the registered components. See ek9 -h E05200 for details.

Incorrect:

RunDemo()
      app <- OrderApp()
      service as OrderService!
      service.process()

Correct:

    RunDemo() with application of OrderApp
      stdout <- Stdout()
Other ways to ask this
  • What triggers E05200 INCOMPATIBLE_GENUS_CONSTRUCTOR?
  • Why does 'app <- MyApplication()' fail to compile in EK9?
  • How do I start a program and its application without calling 'new'?

Coming from another language?

Java Spring: you can technically 'new' a @Configuration or @SpringBootApplication class, and an ApplicationContext is built by SpringApplication.run() - misuse is caught (if at all) at runtime. C#/.NET: Program.cs is conventionally a static entry; nothing stops you constructing a Startup. Go: main() is the entry point and wiring is manual code. EK9: the compiler models program and application as distinct genus types and rejects any constructor call on them (E05200), so the entry point and DI blueprint can never be misused as plain objects.

Keywords: register, instantiate, genus, constructor, with application of, program, application, E05200, injection, entry point