Services
The ServiceRegistry is a lightweight, type-keyed service locator that decouples modules from each other. Instead of passing concrete references between modules directly, each module publishes its services to the registry and other modules resolve them by type.
Service marker interface
Section titled โService marker interfaceโAny class you want to register must implement Service:
public interface Service {}This is a marker interface โ no methods required. It simply makes the registryโs type parameter explicit.
Reloadable
Section titled โReloadableโServices that support hot-reload implement Reloadable:
public interface Reloadable { void reload() throws Exception;}ConfigManager and MessageService implement both Service and Reloadable.
Publishing a service
Section titled โPublishing a serviceโFrom inside a module that extends AbstractModule:
@Overridepublic void onEnable() { MyService service = new MyService(plugin); provide(MyService.class, service); // registers under MyService.class key}Directly via the registry:
plugin.services().register(MyService.class, new MyService(plugin));Registering the same type twice throws IllegalStateException โ one service per type, always.
Resolving a service
Section titled โResolving a serviceโFrom inside a module:
MyService service = service(MyService.class); // throws if not registeredOptional<MyService> opt = services().find(MyService.class); // safeFrom anywhere with a plugin reference:
MyService service = plugin.services().get(MyService.class);Lifecycle
Section titled โLifecycleโThe registry is cleared (services.clear()) during CorePlugin.onDisable(), after all modules have been disabled. Services should not be resolved after onDisable() is called.
Example: FoundationModule
Section titled โExample: FoundationModuleโThe reference FoundationModule shows how core services are published so all later modules can consume them:
@Overridepublic void onEnable() { ConfigManager configs = new ConfigManager(plugin); provide(ConfigManager.class, configs);
MessageService messages = new MessageService(plugin); provide(MessageService.class, messages);
SchedulerService scheduler = new SchedulerService(plugin); provide(SchedulerService.class, scheduler);
ListenerRegistry listeners = new ListenerRegistry(plugin); provide(ListenerRegistry.class, listeners);}A CommandModule that starts after FoundationModule can then do:
MessageService messages = service(MessageService.class);CommandRegistry commands = new CommandRegistry(plugin, messages);provide(CommandRegistry.class, commands);