001    /*****************************************************************************
002     * Copyright (c) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     * Idea by Rachel Davies, Original code by various                           *
009     *****************************************************************************/
010    package org.picocontainer;
011    
012    /**
013     * This is the core interface used for registration of components with a container. It is possible to register {@link
014     * #registerComponentImplementation(Object,Class) an implementation class}, {@link #registerComponentInstance(Object) an
015     * instance} or {@link #registerComponent(ComponentAdapter) a ComponentAdapter}.
016     *
017     * @author Paul Hammant
018     * @author Aslak Hellesøy
019     * @author Jon Tirsén
020     * @version $Revision: 3233 $
021     * @see <a href="package-summary.html#package_description">See package description for basic overview how to use PicoContainer.</a>
022     * @since 1.0
023     */
024    public interface MutablePicoContainer extends PicoContainer {
025    
026        /**
027         * Register a component.
028         *
029         * @param componentKey            a key that identifies the component. Must be unique within the container. The type
030         *                                of the key object has no semantic significance unless explicitly specified in the
031         *                                documentation of the implementing container.
032         * @param componentImplementation the component's implementation class. This must be a concrete class (ie, a
033         *                                class that can be instantiated).
034         * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
035         *         value can be safely ignored, as one of the <code>getXXX()</code> methods of the
036         *         {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
037         * @throws PicoRegistrationException if registration of the component fails.
038         * @see #registerComponentImplementation(Object,Class,Parameter[]) a variant of this method that allows more control
039         *      over the parameters passed into the componentImplementation constructor when constructing an instance.
040         */
041        ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation);
042    
043        /**
044         * Register a component and creates specific instructions on which constructor to use, along with
045         * which components and/or constants to provide as constructor arguments.  These "directives" are
046         * provided through an array of <tt>Parameter</tt> objects.  Parameter[0] correspondes to the first constructor
047         * argument, Parameter[N] corresponds to the  N+1th constructor argument.
048         * <h4>Tips for Parameter usage</h4>
049         * <ul>
050         * <li><strong>Partial Autowiring: </strong>If you have two constructor args to match and you only wish to specify one of the constructors and 
051         * let PicoContainer wire the other one, you can use: 
052         * <code>new Parameter[]{<strong>new ComponentParameter()</strong>, new ComponentParameter("someService"}</code>
053         * The default constructor for the component parameter indicates auto-wiring should take place for 
054         * that parameter.
055         * </li>
056         * <li><strong>Force No-Arg constructor usage:</strong> If you wish to force a component to be constructed with
057         * the no-arg constructor, use a zero length Parameter array.  Ex:  <code>new Parameter[] {}</code> 
058         * <ul>
059         * 
060         *
061         * @param componentKey            a key that identifies the component. Must be unique within the container. The type
062         *                                of the key object has no semantic significance unless explicitly specified in the
063         *                                documentation of the implementing container.
064         * @param componentImplementation the component's implementation class. This must be a concrete class (ie, a
065         *                                class that can be instantiated).
066         * @param parameters              an array of parameters that gives the container hints about what arguments to pass
067         *                                to the constructor when it is instantiated. Container implementations may ignore
068         *                                one or more of these hints.  
069         * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
070         *         value can be safely ignored, as one of the <code>getXXX()</code> methods of the
071         *         {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
072         * @throws PicoRegistrationException if registration of the component fails.
073         * @see org.picocontainer.Parameter
074         * @see org.picocontainer.defaults.ConstantParameter
075         * @see org.picocontainer.defaults.ComponentParameter
076         */
077        ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters);
078    
079        /**
080         * Register a component using the componentImplementation as key. Calling this method is equivalent to calling
081         * <code>registerComponentImplementation(componentImplementation, componentImplementation)</code>.
082         *
083         * @param componentImplementation the concrete component class.
084         * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
085         *         value can be safely ignored, as one of the <code>getXXX()</code> methods of the
086         *         {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
087         * @throws PicoRegistrationException if registration fails.
088         */
089        ComponentAdapter registerComponentImplementation(Class componentImplementation);
090    
091        /**
092         * Register an arbitrary object. The class of the object will be used as a key. Calling this method is equivalent to
093         * calling     * <code>registerComponentImplementation(componentImplementation, componentImplementation)</code>.
094         *
095         * @param componentInstance
096         * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
097         *         value can be safely ignored, as one of the <code>getXXX()</code> methods of the
098         *         {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
099         * @throws PicoRegistrationException if registration fails.
100         */
101        ComponentAdapter registerComponentInstance(Object componentInstance);
102    
103        /**
104         * Register an arbitrary object as a component in the container. This is handy when other components in the same
105         * container have dependencies on this kind of object, but where letting the container manage and instantiate it is
106         * impossible.
107         * <p/>
108         * Beware that too much use of this method is an <a href="http://docs.codehaus.org/display/PICO/Instance+Registration">antipattern</a>.
109         *
110         * @param componentKey      a key that identifies the component. Must be unique within the conainer. The type of the
111         *                          key object has no semantic significance unless explicitly specified in the implementing
112         *                          container.
113         * @param componentInstance an arbitrary object.
114         * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
115         *         value can be safely ignored, as one of the <code>getXXX()</code> methods of the
116         *         {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
117         * @throws PicoRegistrationException if registration fails.
118         */
119        ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance);
120    
121        /**
122         * Register a component via a ComponentAdapter. Use this if you need fine grained control over what
123         * ComponentAdapter to use for a specific component.
124         * 
125         * @param componentAdapter the adapter
126         * @return the same adapter that was passed as an argument.
127         * @throws PicoRegistrationException if registration fails.
128         */
129        ComponentAdapter registerComponent(ComponentAdapter componentAdapter);
130    
131        /**
132         * Unregister a component by key.
133         * 
134         * @param componentKey key of the component to unregister.
135         * @return the ComponentAdapter that was associated with this component.
136         */
137        ComponentAdapter unregisterComponent(Object componentKey);
138    
139        /**
140         * Unregister a component by instance.
141         * 
142         * @param componentInstance the component instance to unregister.
143         * @return the ComponentAdapter that was associated with this component.
144         */
145        ComponentAdapter unregisterComponentByInstance(Object componentInstance);
146    
147        /**
148         * Make a child container, using the same implementation of MutablePicoContainer as the parent.
149         * It will have a reference to this as parent.  This will list the resulting MPC as a child.
150         * Lifecycle events will be cascaded from parent to child
151         * as a consequence of this.
152         * 
153         * @return the new child container.
154         * @since 1.1
155         */
156        MutablePicoContainer makeChildContainer();
157    
158        /**
159         * Add a child container. This action will list the the 'child' as exactly that in the parents scope.
160         * It will not change the child's view of a parent.  That is determined by the constructor arguments of the child
161         * itself. Lifecycle events will be cascaded from parent to child
162         * as a consequence of calling this method.
163         * 
164         * @param child the child container
165         * @return <code>true</code> if the child container was not already in.
166         * @since 1.1
167         */
168        boolean addChildContainer(PicoContainer child);
169    
170        /**
171         * Remove a child container from this container. It will not change the child's view of a parent.
172         * Lifecycle event will no longer be cascaded from the parent to the child.
173         * 
174         * @param child the child container
175         * @return <code>true</code> if the child container has been removed.
176         * @since 1.1
177         */
178        boolean removeChildContainer(PicoContainer child);
179        
180    }