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 }