Skip to content

Spring like Dependency Injection for Modded Minecraft

Notifications You must be signed in to change notification settings

Tamaized/Beanification

Repository files navigation

Beanification

All Rights Reserved

  • This library may only be used as a dependency in software projects.
  • Modification is prohibited. (Pull Requests are allowed)
  • This library is allowed to be repackaged, unmodified, into your own binaries for distribution.
    • Repackaging as shown below with the Gradle Shadow plugin is allowed, and encouraged.
  • Redistribution of this library as a standalone product is prohibited.
  • Attribution is not required.

Gradle

  • ModDevGradle is recommended.
    • (version 2.0.76 is being used for this example)
  • The gradle shadow plugin is recommended.
plugins {
	...
	id 'net.neoforged.moddev' version "${mdg_version}"
	id 'com.gradleup.shadow' version '8.3.3'
}

...

configurations {
	shade
}

...

shadowJar {
	archiveClassifier.set('')
	configurations = [project.configurations.shade]
	relocate 'tamaized.beanification', 'your.package.beanification'
}

...

repositories {
	...
	maven {
		name 'Beanification'
		url 'https://maven.tamaized.com/releases/'
	}
}

...

dependencies {
	...
	def beanification = "tamaized:beanification:${project.minecraft_version}-${project.beanification_version}"
	implementation beanification
	shade beanification
	testImplementation "${beanification}:tests"
	testCompileOnly "${beanification}:test-sources"
}

...

build.dependsOn shadowJar

Setup

In your main @Mod class

@Mod("modid")
public class YourMod {

	static {
		// (Optional) Configure the BeanContext, must be called before #init
		BeanContext.configure()
			.loggingSettings().enableInjectInto();

		// General Setup
		BeanContext.init();

		// This overload can be used instead to register beans directly
		BeanContext.init(context -> {
			context.register(YourComponent.class, new YourComponent());
			context.register(YourComponent.class, "someName", new YourExtendedComponent());
		});
	}

	@Autowired
	private YourComponent yourComponent; // Injected at runtime, not actually null.

	@Autowired("someName")
	private YourComponent yourNamedComponent; // Will be an instance of YourExtendedComponent

	public YourMod() {
		// Enables @Autowired to function with non-static fields in the main @Mod class
		BeanContext.injectInto(this);
	}

}

For further details, view the javadoc for:

  • Autowired
  • Bean
  • Component
  • PostConstruct
  • Configurable

Enable @Configurable

ModDevGradle 2.0.X is required

A gradle plugin is required for this annotation to work as it modifies bytecode during compile time to inject BeanContext.injectInto(this) into every constructor.

It even works if the class does not have any constructor defined.

The injection happens before each RETURN (b1) (177) opcode

buildscript {
	repositories{
		maven {
			name 'Beanification'
			url 'https://maven.tamaized.com/releases/'
		}
	}
	dependencies {
		classpath "tamaized:beanification:${minecraft_version}-${beanification_version}:gradle"
	}
}

plugins {
	...
}

apply plugin: 'tamaized.beanification'

This only works for Intellij run configs and the gradle classes (build) task! Other IDEs are unsupported at this time.

@Configurable
public class MyItem extends Item {

	@Autowired
	private MyComponent myComponent;

	public MyItem() {
		super();
		z();
		// BeanContext.injectInto(this) <- compile time injection here
	}

	protected MyItem(int x) {
		this();
		x.y();
		z();
		// BeanContext.injectInto(this) <- compile time injection here
	}

	private void z() {
		// Will NPE
		// The injection happens at the very end of constructors
		// If you need beans during constructors themselves, use constructor injection
		myComponent.apply();
	}

	public void w() {
		// Will not NPE
		// Assuming this is invoked after the object constructor has finished
		myComponent.apply();
	}

}

Donations

https://ko-fi.com/tamaized

https://www.patreon.com/Tamaized

About

Spring like Dependency Injection for Modded Minecraft

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published