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 map; private List, 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, 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, Object> cache){ Injection annotation = parameter.getAnnotation(Injection.class); if(annotation != null) return this.map.get(annotation.name()); for(BiFunction, 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); }else{ cache.put(type, injection); result = injection; } } } return result; } }