alepha@docs:~/docs/concepts$
cat 6-dependency-injection.md
1 min read
Last commit:

#Dependency Injection (DI)

Alepha uses a Service Locator pattern wrapped in a strictly typed container. If you come from Java (Spring) or Angular, this will feel familiar. If you come from Express, this might feel new.

#Why do we need this?

  1. Testing: You can swap a real database for an in-memory mock without changing your business logic code.
  2. Singleton Management: You don't want to open 50 connections to Redis. You want one connection shared across the app.
  3. Organization: It forces you to structure your code into logical units (Services) rather than a mess of loose functions.

#Injecting Services ($inject)

In Alepha, you don't use constructor(private service: Service). You use $inject.

typescript
 1import { $inject } from "alepha"; 2import { Database } from "./Database"; 3  4class UserService { 5  // Alepha resolves this dependency lazily when the app starts 6  db = $inject(Database); 7  8  async get(id: string) { 9    return this.db.users.findById(id);10  }11}

#Swapping Implementations

Let's say you have an EmailProvider.

typescript
1export class EmailProvider {2  async send(to: string, body: string) {3    // Send via SMTP4  }5}

In development, you don't want to spam real emails. You want to log them to the console.

typescript
1export class ConsoleEmailProvider extends EmailProvider {2  async send(to: string, body: string) {3    console.log(`[EMAIL TO ${to}]: ${body}`);4  }5}

In your main.ts:

typescript
 1const app = Alepha.create(); 2  3if (process.env.NODE_ENV === 'development') { 4  // Magic! 5  // Everywhere 'EmailProvider' is injected, 'ConsoleEmailProvider' will be used instead. 6  app.with({ 7    provide: EmailProvider, 8    use: ConsoleEmailProvider 9  });10}11 12run(app);

#Lifecycle Hooks

Services in Alepha have a lifecycle. You can hook into it using $hook.

  • configure: Setup configuration, read env vars.
  • start: Connect to databases, open ports.
  • ready: App is live, start cron jobs.
  • stop: Graceful shutdown, close connections.
typescript
 1class Database { 2  onStart = $hook({ 3    on: "start", 4    handler: async () => { 5      console.log("Connecting to DB..."); 6      await this.client.connect(); 7    } 8  }); 9 10  onStop = $hook({11    on: "stop",12    handler: async () => {13      await this.client.close();14    }15  });16}

You don't call these manually. run(alepha) handles the orchestration for you.

On This Page
No headings found...
ready
mainTypeScript
UTF-8concepts_dependency_injection.md