Skip to content

Injection Annotations

Maksym Uimanov edited this page Feb 12, 2026 · 1 revision

Injection Annotations

The injection annotations provide the core dependency injection and metadata processing infrastructure for the Temporal API framework. These annotations enable automatic registration, configuration, and execution of various framework components including event handlers, processors, strategies, and factories.

Responsibilities / Purpose

The injection annotations are responsible for:

  • Dependency Management: Automatic injection and registration of framework components
  • Event Handling: Declarative registration of event handlers for Minecraft and mod events
  • Metadata Processing: Configuration of annotation processors and processing strategies
  • Factory Registration: Automatic registration of factory classes for object creation
  • Configuration Management: Registration of mod configuration classes
  • Component Lifecycle: Managing the initialization and execution order of framework components

How it works

The injection system operates through a multi-layered processing approach:

  1. Component Discovery: The framework scans classes for injection annotations during initialization
  2. Registration: Components are automatically registered in appropriate registries or pools
  3. Dependency Resolution: Dependencies between components are resolved and injected
  4. Execution: Components are executed at the appropriate time in the mod lifecycle
  5. Context Management: Components are provided with necessary context and dependencies

The injection annotations are processed by the core framework during mod initialization, ensuring proper setup before any game logic executes.

How to use / Configure

@Handler

Registers event handlers for specific Minecraft or mod events.

@Handler(FMLLoadCompleteEvent.class)
public class ExampleHelloWorldEventHandler implements EventHandler {
    @Override
    public void handle() {
        this.subscribeModEvent(FMLLoadCompleteEvent.class, event -> {
            System.out.println("Hello World!");
        }, EventPriority.HIGHEST);
    }
}

Parameters:

  • value (Class<? extends Event>): The event class to handle
  • override (Class<? extends EventHandler>): Optional override handler class

@Processor

Registers annotation processors for custom metadata processing.

@Processor(ExampleAnnotationProcessor.NAME)
public class ExampleAnnotationProcessor extends AbstractAnnotationProcessor {
    public static final String NAME = "example";

    @Override
    public void process() {
        this.processAll(MetadataLayer.SIMPLE_STRATEGY_CONSUMER, ModContext.NEO_MOD.getClasses());
    }
}

Parameters:

  • value (String): The processor name/identifier
  • override (Class<? extends AnnotationProcessor>): Optional override processor class

@Strategy

Registers annotation processing strategies for specific annotation types.

@Strategy(ExampleAnnotationFieldStrategy.EXAMPLE_FIELD)
public class ExampleAnnotationFieldStrategy implements FieldAnnotationStrategy<ExampleAnnotation> {
    public static final String EXAMPLE_FIELD = "example_field";

    @Override
    public void execute(Field field, Object object, ExampleAnnotation annotation) throws Exception {
        System.out.println(field.getName() + " : " + annotation.value());
    }

    @Override
    public Class<ExampleAnnotation> getAnnotationClass() {
        return ExampleAnnotation.class;
    }

    @Override
    public ProcessorScope getProcessorScope() {
        return new ProcessorScope(ExampleAnnotationProcessor.NAME);
    }
}

Parameters:

  • value (String): The strategy pool identifier
  • override (Class<? extends AnnotationStrategy>): Optional override strategy class

@Injected

Marks classes for automatic injection and registration as framework components.

@Injected
public final class ExampleItemFactory extends ItemFactory implements SwordSubFactory,
        BowSubFactory,
        CrossbowSubFactory,
        ArmorSubFactory,
        SignSubFactory,
        HangingSignSubFactory,
        BoatSubFactory,
        SpawnEggSubFactory,
        SmithingTemplateSubFactory,
        BannerPatternSubFactory,
        MusicDiscSubFactory,
        InstrumentSubFactory {
}

Parameters:

  • value (String): Optional component identifier
  • isContextObject (boolean): Whether this is a context object (default: true)
  • mandatoryMod (String): Optional mandatory mod dependency

@RegisterFactory

Registers factory classes for automatic dependency injection.

public final class ExampleFactories {
    @RegisterFactory
    public static final ExampleItemFactory ITEM_FACTORY = new ExampleItemFactory();
}

@RegisterConfig

Registers mod configuration classes with specific configuration types.

@RegisterConfig(ModConfig.Type.COMMON)
public class ExampleConfig {
    @TranslateAmericanEnglish("Hello World Config")
    public static volatile ModConfigSpec.ConfigValue<Boolean> sayHelloConfigValue;

    public ExampleConfig(ModConfigSpec.Builder builder) {
        sayHelloConfigValue = builder.comment("Whether to say \"Hello World\" or not")
                .translation("config.example.hello_world")
                .define("Say Hello World", true);
    }
}

Parameters:

  • value (ModConfig.Type): The configuration type (COMMON, CLIENT, SERVER)

@Inject

Marks fields or parameters for dependency injection.

public class ExampleService {
    @Inject
    private ExampleDependency dependency;
    
    @Inject("customName")
    private AnotherDependency customDependency;
}

Parameters:

  • value (String): Optional injection name/qualifier

@Dependency

Marks fields as dependencies that should be resolved before component initialization.

public class ExampleComponent {
    @Dependency("exampleService")
    private ExampleService service;
}

Parameters:

  • value (String): The dependency identifier

@Execute

Marks methods for execution during specific phases of mod initialization.

public class ExampleExecutor {
    @Execute(mod = "example_mod")
    public void executeTask() {
        // Custom execution logic
    }
}

Parameters:

  • mod (String): Optional mod identifier for mod-specific execution

Extension / Customization Points

The injection system can be extended by:

  1. Custom Processors: Create new annotation processors for custom metadata processing
  2. Custom Strategies: Implement new processing strategies for specific annotation types
  3. Custom Handlers: Create event handlers for new event types
  4. Custom Factories: Implement factory classes for specialized object creation
  5. Override Mechanisms: Use override parameters to replace default implementations

When to use

Use injection annotations when:

  • Creating framework components that need automatic registration
  • Implementing custom annotation processing logic
  • Creating event handlers for Minecraft or mod events
  • Setting up mod configuration
  • Creating factory classes for object creation
  • Managing dependencies between components
  • Implementing custom metadata processing strategies

Best Practices

  • Use @Injected for framework components that need automatic registration
  • Use @Handler for event handling to ensure proper event subscription
  • Use @Processor and @Strategy for custom annotation processing
  • Use @RegisterConfig for mod configuration to ensure proper loading
  • Use @Inject for dependency injection within framework components
  • Use @Dependency for explicit dependency declaration
  • Use @Execute for initialization tasks that need specific timing
  • Use @RegisterFactory for factory classes that provide object creation services

Clone this wiki locally