70 lines
No EOL
2.2 KiB
Java
70 lines
No EOL
2.2 KiB
Java
package dev.peerat.framework;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.Parameter;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.function.BiFunction;
|
|
|
|
public class DependencyInjector{
|
|
|
|
private Map<String, Object> map;
|
|
private List<BiFunction<Constructor<?>, Parameter, Object>> builders;
|
|
private Object[] injections;
|
|
|
|
public DependencyInjector(){
|
|
this.map = new HashMap<>();
|
|
this.builders = new ArrayList<>();
|
|
}
|
|
|
|
public DependencyInjector of(String name, Object value){
|
|
this.map.put(name, value);
|
|
return this;
|
|
}
|
|
|
|
public DependencyInjector of(BiFunction<Constructor<?>, Parameter, Object> builder){
|
|
this.builders.add(builder);
|
|
return this;
|
|
}
|
|
|
|
public DependencyInjector of(Object... injections){
|
|
if(this.injections == null){
|
|
this.injections = injections;
|
|
return this;
|
|
}
|
|
Object[] copy = new Object[this.injections.length+injections.length];
|
|
System.arraycopy(this.injections, 0, copy, 0, this.injections.length);
|
|
System.arraycopy(injections, 0, copy, this.injections.length, injections.length);
|
|
this.injections = copy;
|
|
return this;
|
|
}
|
|
|
|
Object applyDependency(Constructor<?> constructor, Parameter parameter, Map<Class<?>, Object> cache){
|
|
Injection annotation = parameter.getAnnotation(Injection.class);
|
|
if(annotation != null){
|
|
Object result = this.map.get(annotation.value());
|
|
if(result == null) throw new IllegalArgumentException("No depdency named "+annotation.value()+" ("+this.map.keySet()+") in constructor "+constructor);
|
|
return result;
|
|
}
|
|
for(BiFunction<Constructor<?>, Parameter, Object> function : builders){
|
|
Object result = function.apply(constructor, parameter);
|
|
if(result != null) return result;
|
|
}
|
|
if(this.injections == null) return null;
|
|
Class<?> type = parameter.getType();
|
|
Object result = null;
|
|
for(Object injection : injections){
|
|
if(type.isAssignableFrom(injection.getClass())){
|
|
if(cache.containsKey(type)){
|
|
throw new IllegalArgumentException("Double dependency for type "+type+", can be in constructor "+constructor);
|
|
}else{
|
|
cache.put(type, injection);
|
|
result = injection;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
} |