Skip to main content
Essential uses a dependency injection (DI) system based on Kodein to provide access to its services and APIs. This allows you to retrieve instances of Essential’s components without manually managing their lifecycle.

Getting instances

get

Retrieve an instance from Essential’s DI container.
import gg.essential.api.utils.get
import gg.essential.api.utils.MinecraftUtils
import gg.essential.api.utils.mojang.MojangAPI

// Get MinecraftUtils instance
val minecraftUtils = get<MinecraftUtils>()

// Get MojangAPI instance
val mojangAPI = get<MojangAPI>()

// Use the instances
minecraftUtils.sendMessage("Hello!")
The get() function uses Kotlin’s reified type parameters, making it very concise in Kotlin code. In Java, use DI.INSTANCE.get(Class) instead.

Checking initialization

initialised

Check if Essential’s DI system has been initialized.
import gg.essential.api.utils.initialised
import gg.essential.api.utils.get
import gg.essential.api.utils.MinecraftUtils

fun safelyAccessDI() {
    if (initialised) {
        val minecraftUtils = get<MinecraftUtils>()
        minecraftUtils.sendMessage("DI is ready!")
    } else {
        println("Essential DI not yet initialized")
    }
}

Available services

You can retrieve any of Essential’s API interfaces through the DI system:

Utility APIs

import gg.essential.api.utils.*
import gg.essential.api.utils.mojang.MojangAPI

// Minecraft utilities
val minecraftUtils = get<MinecraftUtils>()

// Mojang API client
val mojangAPI = get<MojangAPI>()

// GUI utilities
val guiUtil = get<GuiUtil>()

// Trusted hosts utility
val trustedHostsUtil = get<TrustedHostsUtil>()

// Web utilities
val webUtil = get<WebUtil>()

Profile APIs

import gg.essential.api.profile.*

// Profile manager
val profileManager = get<ProfileManager>()

Practical examples

Service wrapper class

import gg.essential.api.utils.get
import gg.essential.api.utils.MinecraftUtils
import gg.essential.api.utils.mojang.MojangAPI

class MyModServices {
    private val minecraftUtils by lazy { get<MinecraftUtils>() }
    private val mojangAPI by lazy { get<MojangAPI>() }
    
    fun sendWelcomeMessage() {
        minecraftUtils.sendMessage("Welcome to MyMod!")
    }
    
    suspend fun getPlayerUUID(name: String) {
        mojangAPI.getUUID(name)?.thenAccept { uuid ->
            minecraftUtils.sendMessage("UUID: $uuid")
        }
    }
}

Lazy initialization

import gg.essential.api.utils.get
import gg.essential.api.utils.MinecraftUtils

class MyFeature {
    // Lazy initialization - only retrieved when first accessed
    private val minecraftUtils by lazy { get<MinecraftUtils>() }
    
    fun enable() {
        // DI instance retrieved here on first call
        minecraftUtils.sendMessage("Feature enabled")
    }
}

Error handling

import gg.essential.api.utils.get
import gg.essential.api.utils.initialised
import gg.essential.api.utils.MinecraftUtils

fun safeGetService(): MinecraftUtils? {
    return try {
        if (initialised) {
            get<MinecraftUtils>()
        } else {
            println("DI not initialized yet")
            null
        }
    } catch (e: RuntimeException) {
        println("Failed to get service: ${e.message}")
        null
    }
}

How it works

Essential’s DI system is built on Kodein-DI, a dependency injection framework for Kotlin. When you call get<T>(), the system:
  1. Looks up the requested type in the DI container
  2. Returns an existing instance (singleton) or creates a new one
  3. Throws a RuntimeException if the DI system isn’t initialized or the type isn’t registered

Best practices

Use lazy initialization

Avoid calling get() during class initialization to prevent issues if DI isn’t ready yet:
// Good - lazy initialization
class MyClass {
    private val service by lazy { get<MinecraftUtils>() }
}

// Bad - eager initialization
class MyClass {
    private val service = get<MinecraftUtils>() // May fail if DI not ready
}

Check initialization status

For early-loading code, check if DI is ready before accessing it:
if (initialised) {
    val service = get<MinecraftUtils>()
    // Use service
}

Reuse instances

Store retrieved instances instead of calling get() repeatedly:
// Good
class MyClass {
    private val utils = get<MinecraftUtils>()
    
    fun method1() = utils.sendMessage("Hello")
    fun method2() = utils.isHypixel()
}

// Less efficient
class MyClass {
    fun method1() = get<MinecraftUtils>().sendMessage("Hello")
    fun method2() = get<MinecraftUtils>().isHypixel()
}

API reference

Functions

get
<reified T : Any>() -> T
Retrieve an instance of type T from Essential’s DI container. Throws RuntimeException if DI is not initialized.Kotlin only - uses reified type parameters.

Properties

initialised
Boolean
Returns true if Essential’s DI system has been initialized and is ready to use.Read-only property.
essentialDI
gg.essential.api.DI?
The underlying DI container instance. Prefer using get() instead of accessing this directly.Throws RuntimeException if accessed before initialization.
Do not attempt to set essentialDI in your mod. It is managed internally by Essential and setting it will cause errors.

Build docs developers (and LLMs) love