All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.di.core.BindingTransformer Maven / Gradle / Ivy

Go to download

DataKernel has an extremely lightweight DI with ground-breaking design principles. It supports nested scopes, singletons, object factories, modules and plugins which allow to transform graph of dependencies at startup time without any reflection.

The newest version!
package io.datakernel.di.core;

import io.datakernel.di.impl.BindingLocator;
import org.jetbrains.annotations.NotNull;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import static java.util.stream.Collectors.toList;

/**
 * This is a transformation function that is applied by the {@link Injector injector} to each binding once.
 */
@FunctionalInterface
public interface BindingTransformer {
	BindingTransformer IDENTITY = (bindings, scope, key, binding) -> binding;

	@NotNull Binding transform(BindingLocator bindings, Scope[] scope, Key key, Binding binding);

	@SuppressWarnings("unchecked")
	static  BindingTransformer identity() {
		return (BindingTransformer) IDENTITY;
	}

	/**
	 * Modules export a priority multimap of transformers.
	 * 

* This transformer aggregates such map into one big generator to be used by {@link Injector#compile} method. * The map is converted to a sorted list of sets. * Then for each of those sets, similar to {@link BindingGenerator#combinedGenerator generators}, * only zero or one transformer from that set are allowed to return anything but the binding is was given (being an identity transformer). *

* So if two transformers differ in priority then they can be applied both in order of their priority. */ @SuppressWarnings("unchecked") static BindingTransformer combinedTransformer(Map>> transformers) { List>> transformerList = transformers.entrySet().stream() .sorted(Comparator.comparing(Entry::getKey)) .map(Entry::getValue) .collect(toList()); return (bindings, scope, key, binding) -> { Binding result = binding; for (Set> localTransformers : transformerList) { Binding transformed = null; for (BindingTransformer transformer : localTransformers) { Binding b = ((BindingTransformer) transformer).transform(bindings, scope, key, result); if (b.equals(binding)) { continue; } if (transformed != null) { throw new DIException("More than one transformer with the same priority transformed a binding for key " + key.getDisplayString()); } transformed = b; } if (transformed != null) { result = transformed; } } return result; }; } }