Skip to content

Conversation

@imDMK
Copy link
Owner

@imDMK imDMK commented Dec 28, 2025

No description provided.

@imDMK imDMK changed the title refactor/improve-di-system GH-152 Improve dependency injector system Dec 28, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @imDMK, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a significant internal architectural refactoring, replacing the plugin's custom module and binding system with a more modern, annotation-driven component management framework. This change aims to streamline the plugin's startup process, enhance maintainability, and provide a more flexible and extensible foundation for future development by automating the discovery and lifecycle management of various plugin components like services, configurations, and event handlers. The core plugin class is now much leaner, reflecting the delegation of responsibilities to the new component system.

Highlights

  • DI System Overhaul: The entire dependency injection (DI) system has been refactored, moving from a custom module-based approach with @Bind annotations to a new annotation-driven component management system.
  • New Component-based Architecture: Introduced a ComponentManager and ComponentScanner that automatically discover and process classes annotated with new custom annotations like @Service, @ConfigFile, @Listener, and @Task, simplifying plugin initialization and extensibility.
  • Configuration System Update: The configuration management (ConfigManager renamed to ConfigService) has been updated to integrate with the new component-based DI, removing the ConfigSection abstraction and the InjectorConfigBinder.
  • Database Driver Loading Refinement: The database driver loading mechanism has been updated, with DriverDependencyLoader renamed to DriverLibraryLoader and related classes moved to a new database.driver.library package, streamlining the process.
  • Plugin Core Simplification: The main PlayTimePlugin class has been significantly simplified, delegating complex initialization logic to the new ComponentManager and reducing boilerplate code.
  • Removal of Old Module System: The previous Module and ModuleInitializer system, along with all associated phase interfaces, has been completely removed, indicating a clean break from the old architecture.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant architectural improvement by replacing the custom module-based dependency injection with a more flexible and powerful annotation-driven component model. This change simplifies service registration and management. My review highlights a couple of critical issues with the new implementation: a compilation error in the component setup and the absence of shutdown logic in the plugin's disable phase, which could lead to resource leaks. I have also pointed out a minor inconsistency in a validation message. Overall, this is a very positive refactoring that will enhance the codebase's maintainability once these points are addressed.

metrics = new Metrics(plugin, PLUGIN_METRICS_ID);
ComponentManager componentManager = new ComponentManager(injector, this.getClass().getPackageName())
.setPriorityProvider(new AnnotationPriorityProvider())
.addProcessor();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This call to .addProcessor() is incomplete and will cause a compilation error because the method requires an argument. It appears you intended to register processors for the new component annotations (like @Service, @Listener, etc.). You'll need to add the concrete processor implementations for each component type. To fix the compilation issue for now, I suggest commenting out this line and adding a TODO as a reminder.

                // .addProcessor(); // TODO: Add component processors

Comment on lines 44 to 45
void disable() {
Validator.ifNotNull(configManager, (manager) -> {
manager.saveAll();
manager.clearAll();
});
Validator.ifNotNull(repositoryManager, RepositoryManager::close);
Validator.ifNotNull(databaseManager, DatabaseManager::shutdown);
Validator.ifNotNull(messageService, MessageService::shutdown);
Validator.ifNotNull(taskScheduler, TaskScheduler::shutdown);
Validator.ifNotNull(liteCommands, LiteCommands::unregister);
Validator.ifNotNull(metrics, Metrics::shutdown);

PlayTimeApiProvider.unregister();

logger.info("%s plugin disabled successfully.", PREFIX);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The disable() method is empty, which is a major regression from the previous implementation. The old version correctly shut down various services (saving configs, closing database connections, stopping schedulers) to prevent resource leaks and ensure data is saved. This critical shutdown logic needs to be restored within the new component-based architecture. A common pattern is to have components that require cleanup implement an interface like AutoCloseable, and then have the ComponentManager trigger their shutdown during the disable phase.

    void disable() {
        // TODO: Implement shutdown logic for all managed components, for example:
        // componentManager.shutdownAll();
    }

) {
this.logger = Validator.notNull(logger, "logger");
this.configManager = Validator.notNull(configManager, "configManager");
this.configService = Validator.notNull(configService, "configManager");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The validation message for configService uses the string "configManager". This is inconsistent and could be misleading if a NullPointerException occurs, as the error message would refer to configManager. For clarity and easier debugging, the name in the error message should match the variable being checked.

Suggested change
this.configService = Validator.notNull(configService, "configManager");
this.configService = Validator.notNull(configService, "configService");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants