MentaContainer

Rev

Rev 4 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.mentacontainer;

/**
 * A very simple container that provides:
 * <ul>
 *   <li> Bean instantiation (duh!)</li>
 *   <li> Constructor injection for bean setup</li>
 *   <li> Setter injection for bean setup</li>
 *   <li> Auto-wiring based on name and type</li>
 *   <li> Singleton</li>
 *   <li> Injection</li>
 * </ul>
 *
 * It does not get much simpler than that.
 *
 * @author sergio.oliveira.jr@gmail.com
 *
 */

public interface Container {
       
        /**
         * Get an instance from the container.
         *
         * The instance will be fully initialized (constructor and/or setters) and fully wired.
         *
         * @param key The key representing the bean to return. The name of the bean in the container.
         * @return The fully initialized and wired bean.
         */

        public Object get(String key);
       
        /**
         * Configure a bean to be returned with the given implementation when {@link #get(String)} is called.
         *
         * @param key The key representing the bean to return. The name of the bean in the container.
         * @param klass The class used to instantiate the bean, in other words, its implementation.
         * @param singleton A boolean to indicate if this bean will be a singleton.
         * @return The container itself. (Fluent API)
         */

        public Container ioc(String key, Class<? extends Object> klass, boolean singleton);
       
        /**
         * Same as {@link #ioc(String, Class<? extends Object>, singleton)} except that it assumes
         * singleton is false.
         *
         * @param key
         * @param klass
         * @return The container itself. (Fluent API)
         */

        public Container ioc(String key, Class<?extends Object> klass);
       
        /**
         * Configure a bean dependency to be auto-wired by the container. The dependency should be
         * an interface otherwise an exception is thrown. It works like that:
         *
         * Whenever the container returns a bean, it checks to see if it has a property named <i>property</i>
         * and if the type of the property is <i>klass</i>. If it does, then it looks for a bean named
         * <i>source</i> and injects it inside the first bean it is returning. This approach is recursive
         * so all properties are checked up the class hierarchy, until it reaches Object.
         *
         * @param property a bean property that will require another bean, in other words, the required
         *                                 bean will be injected in the property of the bean been requested from the container. (auto-wiring by name)
         * @param klass an interface, not an implementation, defining the type of the auto-wiring. (auto-wiring by type)
         * @param source The dependency itself, coming from the container as well, in other words, the bean that will be injected in the original bean
         * @return The container itself. (Fluent API)
         */

        public Container autowire(String property, Class<? extends Object> klass, String source);
       
        /**
         * Same as {@link #get(String)} except that it passes the property name as the source name, in other words,
         * the property name is the same as the bean name that will be injected as the dependency.
         *
         * @param property
         * @param klass
         * @return The container itself. (Fluent API)
         */

        public Container autowire(String property, Class<? extends Object> klass);
       
        /**
         * Add a constructor parameter that will be used by the container to instantiate the bean. The container keeps the order of the parameters
         * in case this method gets called more than once for the same bean, in other words, it assumes that the bean constructor takes more than
         * one parameter.
         *
         * @param key The key representing the bean to return. The name of the bean in the container.
         * @param obj The constructor parameter value.
         * @return The container itself. (Fluent API)
         */

        public Container init(String key, Object obj);
       
        /**
         * Add a property that will be injected by the container in the bean it instantiates. To be not confused with auto-wiring. Here we are just passing
         * static values to be injected in the bean. Auto-wiring wires anything because it is based on interfaces and NOT on implementations.
         *
         * @param key The key representing the bean to return. The name of the bean in the container.
         * @param name The name of the bean property (bean must provide a property setter)
         * @param obj The value of the property that will be injected.
         * @return The container itself. (Fluent API)
         */

        public Container set(String key, String name, Object obj);
       
        /**
         * Take a given bean and populate its properties with other beans coming from this container. Perhaps you can call this auto-wiring.
         * You basically checking properties of the given bean and looking for values (by name and type!) inside the container. And injecting
         * in the given bean, in other words, populating it.
         *
         * @param bean The bean to be populated with other beans from the container.
         * @return The container itself. (Fluent API)
         */

        public Container populate(Object bean);
}