Dependency Injection¶
Dependency injection supports the dependency inversion principle by injecting dependencies into the class definitions
instead of hardcoding them. You'll need dependency injection when using JDA-Commands, because
most of your classes, like interaction controllers or middlewares aren't instantiated by
you anymore.
JDA-Commands creates one instance of an interaction controller class per runtime. To allow the injection of own Objects in these instances, JDA-Commands provides an interface to integrate a dependency injection framework.
Tip
Since JDA-Commands is a fundamental part of your discord bot and dependency injection is deeply connected with it, your bot should use a dependency injection framework for all your tasks.
Default Dependency Injection Framework - Guice¶
Warning
For information on how to use Googles Guice, please visit their documentation. This wiki only covers the configuration part.
If your using JDA-Commands via the io.github.kaktushose:jda-commands:VERSION artifact, an integration for
Googles Guice is shipped by default.
Interaction controller classes¶
You can annotate the constructor (or fields) of your interaction controller class with @Inject
to either inject framework components (properties) or your own
objects provided by a custom Injector.
You can directly inject following classes:
JDACommandsDefinitionsJDA(the instance bound to this interaction)I18nMessageResolverEmojiResolverPlaceholderResolverDescriptorClassFinderJDACIntrospection(see here fore more information)
If you need any other JDACProperty, just inject them via the JDACIntrospection instance manually.
During instantiation (inside the constructor) of an interaction controller class, the scope is set to JDACScope#RUNTIME.
Example
@Interaction
class MyCommand {
@Inject
MyCommand(JDA jda, //(1)
MessageResolver resolver, //(2)
JDACIntrospection introspection) { //(3)
// do whatever you want with them
}
@Command("hello")
public void onCommand(CommandEvent event) {
...
}
}
- the
JDAinstance used. If you're usingShardManager, this is the one the guild executing the command is paired to. - the
MessageResolverinstance used by JDA-Commands. It's a "framework component". - the
JDACIntrospectioninstance used in this scope with scope set toJDACScope#RUNTIME
Configuration (providing a custom Injector)¶
To customize this integration you can pass an instance of GuiceExtensionData
to the JDA-Commands builder, which allows you to provide an own instance of Injector.
Configuring Guice
@Implementation annotation¶
JDA-Commands has many interfaces to customize specific framework behaviour.
If you're using the Guice integration you can benefit from the convenient @Implementation
annotation.
This annotation allows the automatic instantiation and registration for implementations of following interfaces:
Note
If you're annotating an implementation of Middleware, Validator or TypeAdapter you have to provide additional configuration via the @Implementation annotation.
PermissionsProviderGuildScopeProviderErrorMessageFactory@Validator+Implementation.Validator#annotation()setTypeAdapter+Implementation.TypeAdapter#source()&Implementation.TypeAdapter#target()set
The annotated classes will be instantiated with help of com.google.inject.Injector similar to interaction controllers.
Example
Just like in interaction controller methods, you can
inject framework components and custom objects in your classes.
Take a look at the Javadocs of @Implementation to know what you can inject here.
Custom dependency injection integrations¶
If you want to integrate another dependency injection framework, you have to provide your own
implementation of Instantiator.
You can do this by either passing it to the builder or by creating your own extension.