Adding Dependencies
This guide shows you how to inject services and repos into your use-cases.
Overview
Devux uses dependency injection (Inversify) to wire up your components. You don't instantiate classes manually - you declare what you need using inject decorators and the framework provides it.
Adding a Repo to a Use-Case
Steps
- Run
pnpm devux - Select "Endpoints"
- Select "Manage dependencies"
- Choose the endpoint
- Select "Add dependency"
- Choose the repo to inject
Result
The CLI adds the inject decorator and property to your use-case:
typescript
import { injectGetCustomerByEmailRepo } from '@/__internals__/domains/customers/repos/get-customer-by-email/get-customer-by-email.repo.inversify.tokens';
@fullInjectable()
export class CreateCustomerUseCase extends TransactionalUseCase<CreateCustomerRequest> {
@injectGetCustomerByEmailRepo() private readonly getCustomerByEmailRepo!: IGetCustomerByEmailRepo;
protected override async _execute(input: CreateCustomerRequest): Promise<void> {
// Now you can use this.getCustomerByEmailRepo.execute(...)
}
}Adding a Service to a Use-Case
Steps
- Run
pnpm devux - Select "Endpoints"
- Select "Manage dependencies"
- Choose the endpoint
- Select "Add dependency"
- Choose the service to inject (domain service or app service)
Result
typescript
import { injectEmailService } from '@/__internals__/app-services/email-service/email-service.inversify.tokens';
@fullInjectable()
export class CreateCustomerUseCase extends TransactionalUseCase<CreateCustomerRequest> {
@injectEmailService() private readonly emailService!: IEmailService;
protected override async _execute(input: CreateCustomerRequest): Promise<void> {
// Now you can use this.emailService
}
}Multiple Dependencies
You can inject as many dependencies as needed:
typescript
@fullInjectable()
export class CreateOrderUseCase extends TransactionalUseCase<CreateOrderRequest> {
@injectCreateOrderRepo() private readonly createOrderRepo!: ICreateOrderRepo;
@injectCalculatePricingService() private readonly pricingService!: ICalculatePricingService;
@injectEmailService() private readonly emailService!: IEmailService;
protected override async _execute(input: CreateOrderRequest): Promise<void> {
const pricing = await this.pricingService.execute({ items: input.items });
const order = await this.createOrderRepo.execute({ ...input, total: pricing.data.total });
await this.emailService.sendOrderConfirmation(input.email, order.data);
}
}Type Safety
All dependencies are type-safe:
- Inject functions are typed to their interface
- Import statements are added automatically
- The tester class is regenerated with the new dependency