Dependency Injection (DI)
How Kythia manages scale and prevents circular dependencies using a centralized container.
Kythia uses a Dependency Injection (DI) Container to solve the common "Circular Dependency" problem found in large Discord bot applications.
The Problem
In a modular bot, addons often need access to core services (like the Database, Logger, or Translator). However, these core services often need to know about the addons to load them.
If you use standard require() calls at the top of your files to access core services, you will likely encounter an error because the files are still being processed by the AddonManager.
The Solution: The Container
The Kythia core initializes all services and places them into a single container object. This container is then "injected" into every command, event, and component at runtime.
Accessing the Container
In Kythia, you have two ways to access the container:
1. Via the execute parameters (Recommended)
The InteractionManager and EventManager automatically pass the container as the second argument to your main functions.
// addons/core/commands/utils/ping.js
module.exports = {
slashCommand: new SlashCommandBuilder().setName('ping')...,
async execute(interaction, container) {
// 💡 The container is provided right here!
const { logger, helpers, t } = container;
logger.info('Ping command executed');
await interaction.reply(await t(interaction, 'core.ping.pong'));
}
}
2. Via the Client
If you are in a utility function where the container isn't directly passed, you can find it attached to the Discord client.
const container = interaction.client.container;
What's inside the Container?
The container holds every critical piece of the application:
| Instance | Description |
|---|---|
logger |
The centralized Winston logger. |
kythiaConfig |
The full kythia.config.js object. |
models |
All initialized Sequelize models (Labyrinth, Adventure, etc.). |
helpers |
Core helper functions (Color, Time, Pagination). |
t |
The translation/i18n function. |
shutdownManager |
Access to uptime and shutdown hooks. |
require() to grab core models or helpers from within an addon folder. Always rely on the container to ensure you're using the same initialized instances as the rest of the bot.