Controllers and Dependency Injection
Controllers and Dependency Injection
Controllers should extend the base Controller class for shared helper behavior.
Constructor Injection
Declare dependencies using static inject:
export class AppController extends Controller {
static inject = [AppInfoService];
constructor(private appInfoService: AppInfoService) {
super();
}
}
The container resolves dependencies when Kernel dispatches the controller action.
Token-Based Providers
The container supports class, string, and symbol tokens. For abstractions, register a token and inject that token.
const APP_CONFIG = "app.config";
const LOGGER = Symbol("logger");
container.register({ provide: APP_CONFIG, useValue: { baseUrl: "https://example.test" } });
container.register({ provide: LOGGER, useFactory: () => new Logger(), singleton: true });
container.register({ provide: UserService, useClass: UserService });
Then inject those tokens from controllers or services:
class UserController extends Controller {
static inject = [APP_CONFIG, LOGGER, UserService];
constructor(private config: { baseUrl: string }, private logger: Logger, private users: UserService) {
super();
}
}
Test-Time Overrides
For tests, keep production wiring and override specific tokens with instance:
container.instance(LOGGER, new FakeLogger());
Request-Scoped Access
Use request-scoped data through the HttpRequest passed into actions.
index(req: HttpRequest) {
const userAgent = req.header('user-agent');
}
Base Controller Helpers
The template base controller includes session helpers:
- requireSession(req)
- sessionGet(req, key)
- sessionPut(req, key, value)
- sessionForget(req, key)
Use these to avoid repeating guard logic in each controller.