Stone.jsDocs
Paradigm

Foundations

Service container & DI

The container is where dependency injection happens. It is the ephemeral context in practice: for each event it resolves the services your handlers ask for and hands them in. The domain declares what it needs; it never goes looking.

#Depend on names, not construction

The principle

When a class builds its own dependencies, it is welded to their concrete types and their wiring. When it declares them and receives them, it depends only on a contract. Inversion of control is what lets the same domain run against different implementations in different contexts.

In Stone.js

Register a service with @Service({ alias }) and it is bound under that name. Any handler or service that destructures the alias in its constructor receives the resolved instance. No new, no imports of implementations, no reflect-metadata.

app/Tasks.tsdeclarativeimperative
import { Service } from '@stone-js/core'

@Service({ alias: 'tasks', singleton: true })
export class TaskService {
  constructor ({ config }) { this.pageSize = config.get('stone.tasks.pageSize', 20) }
}
import { defineService } from '@stone-js/core'

const TaskService = ({ config }) => ({
  pageSize: config.get('stone.tasks.pageSize', 20)
})

export const services = [
  defineService(TaskService, { alias: 'tasks', singleton: true }, true)
]
Ask for what you need by name. The container decides how to build it, and when.

#Singletons are per-event

A singleton: true service is created once per container, which means once per event, not once per process. It is the natural default for services that are stateless within a request. Because the container is discarded after the event, singletons cannot leak between requests.

#Resolving explicitly

Destructured injection covers almost everything. When you need the container itself, for dynamic or conditional resolution, it is available and typed.

app/Tasks.tsts
constructor ({ container }) {
  this.tasks = container.resolve('tasks')          // by alias
  this.mailer = container.make(MailerService)      // by class
}

Stone.js

Your app exists in every runtime. Until you run it.

An open-source project by Stone Foundation
Created by Mr. Stone (Evens Pierre)