package de.renew.plugin.di;


/**
 * {@code ServiceContainer} defines an interface for services in Container.
 * @author Konstantin Simon Maria Moellers
 * @version 2015-10-11
 */
public interface ServiceContainer {
    /**
     * Check for existence of service in Container
     * @param service The service to be checked for
     * @return Boolean representation of check result
     */
    boolean has(Class<?> service);

    /**
     * Returns specified Service from Container
     * @param service The service to be retrieved
     * @return Specified service from container
     * @throws MissingDependencyException when service dependencies can not be resolved
     */
    Object get(Class<?> service) throws MissingDependencyException;

    /**
     * Sets service to given singleton
     * @param service Service to be set
     * @param singleton Singleton where service is to be set
     * @param <T> Generic type Argument for this definition
     */
    <T> void set(Class<?> service, T singleton);

    /**
     * Adds definition to container
     * @param definition Definition to be added to calling container
     */
    void addDefinition(Definition<?> definition);

    /**
     * Removes the service and all associated service definitions from this
     * container. Associated services are those found in the scope of the
     * service instance and provided by methods annotated with
     * {@link de.renew.plugin.annotations.Provides}.
     *
     * @param service Service to unbind from this service container.
     * @throws IllegalArgumentException if the service is not bound to this
     *                                  container.
     */
    void unbind(Class<?> service);
}