https://github.com/funnyguilds/dependency-injector
Blazingly fast and lightweight dependency injection framework for Java 💉
https://github.com/funnyguilds/dependency-injector
dependency-injection dependency-injection-framework panda-lang
Last synced: 8 months ago
JSON representation
Blazingly fast and lightweight dependency injection framework for Java 💉
- Host: GitHub
- URL: https://github.com/funnyguilds/dependency-injector
- Owner: FunnyGuilds
- License: mit
- Created: 2020-07-22T00:30:08.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-03-14T17:43:19.000Z (9 months ago)
- Last Synced: 2025-03-31T04:36:41.776Z (9 months ago)
- Topics: dependency-injection, dependency-injection-framework, panda-lang
- Language: Java
- Homepage:
- Size: 435 KB
- Stars: 18
- Watchers: 1
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: .github/README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Dependency Injection [](https://github.com/dzikoysk/dependency-injector/actions/workflows/maven.yml) [](https://codecov.io/gh/FunnyGuilds/dependency-injector) 
Blazingly fast and lightweight dependency injection framework for Java. Supported operations:
* Creating a new instance of the specified type using Injector _(constructors)_
* Invoking methods using Injector _(methods)_
* Reflection based field injection during instance creation _(fields)_
### Install
Library is available in `panda-repository`:
```xml
panda-repository
https://maven.reposilite.com/releases
```
To use `annotations`, declare the dependency in your `pom.xml`
```xml
org.panda-lang.utilities
di
1.8.0
org.panda-lang.utilities
di-codegen
1.8.0
```
### Usage
Firstly, you have to create `Injector` which keeps all the registered bindings (injected values)
```java
Injector injector = DependencyInjection.createInjector()
// If you are able to register binding at the init time, it's also recommended to use the following structure
Injector injector = DependencyInjection.createInjector(resources -> {
// bind resources
});
```
Injector supports three main ways to bind with a value:
* Binding to the specified type `resources.on()`
* Binding to the specified annotation `resources.annotatedWith()`
* Binding to the verified annotation `resources.annotatedWithTested()` *(safer but slower alternative to `annotatedWith`)*
Each binding supports three ways of assigning value:
* `assignInstance()`/`assignInstance(Supplier)` - binds the specified value/some kind of lazy values
* `assignHandler((, ) -> { /* logic */ })` - binds custom handler
#### Instances
The most common use of DI comes down to some kind of instance assignation:
```java
public static class Bean { }
public interface Custom { }
static class CustomImpl implements Custom { }
static class Service {
public Service(Bean bean, Custom custom) {
assertNotNull(bean);
assertNotNull(custom);
}
}
```
To create `Service` class, just invoke its constructor:
```java
Injector injector = DependencyInjection.createInjector();
// some logic, a few hours later...
injector.getResources().on(Custom.class).assignInstance(new CustomImpl()); // singleton
injector.getResources().on(Bean.class).assignInstance(Bean::new); // new instance per call
Service service = injector.forConstructor(Service.class).newInstance();
```
Full example: [DependencyInjectionInstancesTest.java](https://github.com/FunnyGuilds/dependency-injector/blob/master/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionInstancesTest.java)
#### Fields
```java
class Service {
@Inject
private String fieldOne;
@Inject
private Integer fieldTwo;
}
Injector injector = DependencyInjection.createInjector(resources -> {
resources.on(String.class).assignInstance("Hello Field");
resources.on(Integer.class).assignInstance(7);
});
Service service = injector.newInstanceWithFields(Service.class);
```
Full example: [DependencyInjectionFieldsTest.java](https://github.com/FunnyGuilds/dependency-injector/blob/master/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionFieldsTest.java)
#### Custom logic
Let's build a random example based on these methods using a custom annotation:
```java
@Injectable // mark annotation as DI ready annotation
@Retention(RetentionPolicy.RUNTIME) // make sure that the annotation is visible at runtime
@interface AwesomeRandom { }
static final class Entity {
private final UUID id;
private Entity(@AwesomeRandom UUID random) {
this.id = random;
}
public UUID getId() {
return id;
}
}
```
We'd like to generate a new id per each `Entity` instance with a private constructor. It's also important for us, to support id in two forms:
* String
* UUID
```java
Injector injector = DependencyInjection.createInjector(resources -> {
resources.annotatedWith(AwesomeRandom.class).assignHandler((expectedType, annotation) -> {
if (expectedType.equals(String.class)) {
return UUID.randomUUID().toString();
}
if (expectedType.equals(UUID.class)) {
return UUID.randomUUID();
}
throw new IllegalArgumentException("Unsupported type " + expectedType);
});
});
// Create entities using the injector instance
Entity entityA = injector.newInstance(Entity.class);
Entity entityB = injector.newInstance(Entity.class);
// Print generated values
System.out.println(entityA.getId());
System.out.println(entityB.getId());
```
The output produces some random identifiers as intended 👍
```
e23442b2-f695-41fa-9290-0f1192118a1a
9f92121c-096e-4bdb-b6ad-0901974bbe37
Process finished with exit code 0
```
Full example is available here -> [DependencyInjectionWikiTest.java](https://github.com/FunnyGuilds/dependency-injector/blob/master/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java)