ljacqu/DependencyInjector

View on GitHub
injector/src/main/java/ch/jalu/injector/Injector.java

Summary

Maintainability
A
0 mins
Test Coverage
package ch.jalu.injector;

import javax.annotation.Nullable;
import javax.inject.Provider;
import java.lang.annotation.Annotation;
import java.util.Collection;

/**
 * Dependency injector.
 * <p>
 * Allows you to retrieve singletons and create new instances. By default, it supports field and constructor injection
 * and executes methods annotated with {@code @PostConstruct}. You can obtain an injector and customize its behavior
 * with the {@link InjectorBuilder}.
 */
public interface Injector {

    /**
     * Registers an object as the singleton of the given class. Throws an exception if a singleton is already
     * available for the class.
     *
     * @param clazz the class to register the object for
     * @param object the object
     * @param <T> the type to register the object for
     * @since 0.1
     */
    <T> void register(Class<? super T> clazz, T object);

    /**
     * Registers a provider for the given class. The provider is used whenever the class needs to be instantiated.
     *
     * @param clazz the class to register the provider for
     * @param provider the provider
     * @param <T> the class's type
     * @since 0.3
     */
    <T> void registerProvider(Class<T> clazz, Provider<? extends T> provider);

    /**
     * Registers the provider class to instantiate a given class. The first time the {@code clazz} has to
     * be instantiated, the {@code providerClass} will be instantiated.
     *
     * @param clazz the class to register the provider for
     * @param providerClass the class of the provider
     * @param <T> the class's type
     * @param <P> the provider's type
     * @since 0.3
     */
    <T, P extends Provider<? extends T>> void registerProvider(Class<T> clazz, Class<P> providerClass);

    /**
     * Processes an annotation with an associated object. The actual behavior of this method depends on the
     * configured handlers of the injector. By default it registers the given object for the annotation such
     * that it may be later injected with the annotation as identifier.
     *
     * @param annotation the annotation
     * @param object the object
     * @since 0.1
     */
    void provide(Class<? extends Annotation> annotation, @Nullable Object object);

    /**
     * Retrieves or instantiates an object of the given type (singleton scope).
     *
     * @param clazz the class to retrieve the value for
     * @param <T> the class's type
     * @return object of the class's type
     * @since 0.1
     */
    <T> T getSingleton(Class<T> clazz);

    /**
     * Request-scoped method to instantiate a new object of the given class. The injector does <i>not</i> keep track
     * of it afterwards; it will always return a new instance and forget about it.
     *
     * @param clazz the class to instantiate
     * @param <T> the class's type
     * @return new instance of class T
     * @since 0.1
     */
    <T> T newInstance(Class<T> clazz);

    /**
     * Returns the singleton of the given class if available. This simply returns the instance if present, and
     * otherwise {@code null}. Calling this method will never create any new objects.
     *
     * @param clazz the class to retrieve the instance for
     * @param <T> the class's type
     * @return instance or null if not available
     * @since 0.1
     */
    @Nullable
    <T> T getIfAvailable(Class<T> clazz);

    /**
     * Creates an instance of the given class if all of its dependencies are available. A new instance
     * is returned each time and the created object is not stored in the injector.
     * <p>
     * <b>Note:</b> Currently, all dependencies of the class need to be registered singletons for a new
     * instance to be created. This limitation may be lifted in future versions.
     *
     * @param clazz the class to construct if possible
     * @param <T> the class's type
     * @return instance of the class, or {@code null} if any dependency does not already exist
     */
    @Nullable
    <T> T createIfHasDependencies(Class<T> clazz);

    /**
     * Returns all known singletons of the given type. Typically used
     * with interfaces in order to perform an action without knowing its concrete implementors.
     * Trivially, using {@link Object} as {@code clazz} will return all known singletons.
     *
     * @param clazz the class to retrieve singletons of
     * @param <T> the class's type
     * @return list of singletons of the given type
     * @since 0.1
     */
    <T> Collection<T> retrieveAllOfType(Class<T> clazz);

}