Skip to content

Dependency Injection Setup

DomusJS uses tsyringe as its dependency injection (DI) container.
The infrastructure module provides the registerDomusCore() helper to simplify and centralize the registration of core dependencies.

✅ This ensures that buses, loggers, and other infrastructure services are available across your app without manual wiring.


The registerDomusCore() function:

  • Registers the CommandBus, QueryBus, and EventBus (default: in-memory versions).
  • Registers the Logger implementation you provide.
  • Registers shared utilities like unique ID providers.
  • Prepares the DI container (tsyringe) for application use.

✅ This sets up all core services before you register additional bounded contexts or modules.


import { registerDomusCore, PinoLogger } from '@domusjs/infrastructure';
registerDomusCore({
logger: new PinoLogger()
});

✅ After this call, you can resolve buses, loggers, and core services anywhere in your app:

const commandBus = container.resolve<CommandBus>('CommandBus');
const logger = container.resolve<Logger>('Logger');

While registerDomusCore() sets up in-memory buses by default, you can easily override them with your own implementations or switch to other provided DomusJS integrations as needed:

import {
registerDomusCore,
PinoLogger,
RabbitMQEventBus
} from '@domusjs/infrastructure';
import { MyCommandBusImplementation } from './command-bus';
import { MyQueryBusImplementation } from './query-bus';
registerDomusCore({
logger: new PinoLogger(),
commandBus: new MyCommandBusImplementation(),
queryBus: new MyQueryBusImplementation(),
eventBus: new RabbitMQEventBus(),
});

✅ This keeps the default setup minimal but fully extensible.


While registerDomusCore() handles the core setup (buses, logger, etc.), you’ll often need to register other services or repositories that are specific to your application.

✅ You can register these outside the core helper by using the tsyringe container directly:

import { container } from 'tsyringe';
import { UserRepository } from './repositories/user-repository';
import { PrismaUserRepository } from './repositories/prisma-user-repository';
container.register<UserRepository>('UserRepository', {
useClass: PrismaUserRepository,
});

✅ This pattern allows you to wire up bounded context dependencies, infrastructure services, or any custom components.

ℹ️ Tip:
Always call registerDomusCore() first, so the shared core services are ready before you add additional registrations.


✅ Centralize all DI setup inside your main registerDependencies() function or module.
✅ Always call registerDomusCore() before registering bounded contexts or application-specific services.
✅ Keep bus and logger implementations swappable by sticking to the defined interfaces.
✅ Avoid leaking infrastructure-specific classes into the domain layer.