diff --git a/doc/reference/src/objects.xml b/doc/reference/src/objects.xml index 185b54c2..35c7e81f 100644 --- a/doc/reference/src/objects.xml +++ b/doc/reference/src/objects.xml @@ -37,7 +37,7 @@ Spring.NET's IoC container. The IObjectFactory interface provides an advanced configuration mechanism capable of managing - objects of any nature. IApplicationContext is a sub-interface of IObjectFactory. It adds easier integration with Spring.NET's Aspect Oriented Programming (AOP) features, @@ -51,7 +51,7 @@ IApplicationContext adds more enterprise-specific functionality. The IApplicationContext is a complete superset of the IObjectFactory and is used exclusively - in this chapter when describing Spring's IoC container. + in this chapter in descriptions of Spring's IoC container. If you are new to Spring.NET or IoC containers in general, you may want to consider starting with , which @@ -64,7 +64,7 @@ - The Spring IoC container + Container overview The interface IApplicationContext represents the Spring IoC container and is responsible for instantiating, @@ -82,16 +82,16 @@ already supports such functionality. - Spring provides implementations of the - IApplicationContext interface for use in standalone - and web applications. In standalone applications it is common to create an - instance of an XmlApplicationContext either - programmatically or declaratively in your applications App.config file. In - web applications Spring provides a WebApplicationContext implementation - which is configured by adding a custom HTTP module and HTTP handler to - your Web.config file. See the section on Web Configuration for more - details. + Several implementations of the + IApplicationContext interface are supplied + out-of-the-box with Spring. In standalone applications it is common to + create an instance of an XmlApplicationContext + either programmatically or declaratively in your applications App.config + file. In web applications Spring provides a + WebApplicationContext implementation which is + configured by adding a custom HTTP module and HTTP handler to your + Web.config file. See the section on Web + Configuration for more details. The following diagram is a high-level view of how Spring works. Your application classes are combined with configuration metadata so that after @@ -126,8 +126,8 @@ Spring configuration consists of at least one and typically more than one object definition that the container must manage. XML- based - configuration represents beans as <object/> elements inside a - top-level <objects/> element. + configuration shows these objects as <object/> + elements inside a top-level <objects/> element. These object definitions correspond to the actual objects that make up your application. Typically you define service layer objects, @@ -161,8 +161,8 @@ the assembly name. The value of the id attribute refers to collaborating objects. The XML for referring to collaborating objects is not shown in this example; Dependencies for more information. - + linkend="objects-dependencies">Dependencies for more + information. Spring.NET comes with an XSD schema to make the validation of the XML object definitions a whole lot easier. The XSD document is @@ -217,7 +217,7 @@ <!-- more bean definitions for data access objects go here --> </objects> - In this example, the service layer consists of the class + In the preceeding example, the service layer consists of the class PetStoreService, and two data access objects of the type HibernateAccountDao and HibernateItemDao are based on the NHibernate @@ -400,17 +400,17 @@ Composing XML-based configuration metadata - It can be useful to split up object definitions into multiple - XML files. Often each individual XML configuration file represents a - logical layer or module in your architecture. One way to then load an - application context that is configured from all these XML fragments is - to use the application context constructor. This constructor takes - multiple IResource locations, as was shown in - the previous section. + It can be useful to have object definitions span multiple XML + files. Often each individual XML configuration file represents a + logical layer or module in your architecture. - An alternate approach is to use one or more occurrences of the - <import/> element to load object definitions from another file - (or files). Let's look at a sample: + You can use the IApplicationContext + constructor to load object definitions from all these XML fragments. + This constructor takes multiple IResource + locations, as was shown in the previous section. Alternatively, use + one or more occurrences of the <import/> + element to load object definitions from another file (or files). For + example: <objects xmlns="http://www.springframework.net"> @@ -423,22 +423,20 @@ </objects> - In this example, external object definitions are being loaded - from three files, services.xml, + In the preceeding example, external object definitions are being + loaded from three files, services.xml, messageSource.xml, and - themeSource.xml. All location paths are considered - relative to the definition file doing the importing, so - services.xml in this case must be in the same - directory as the file doing the importing, while - messageSource.xml and - themeSource.xml must be in a + themeSource.xml. All location paths are relative to + the definition file doing the importing, so + services.xml must be in the same directory as the + file doing the importing, while messageSource.xml + and themeSource.xml must be in a resources location below the location of the - importing file. As you can see, a leading slash is actually ignored, - but given that these are considered relative paths, it is probably - better form not to use the slash at all. The contents of the files - being imported, including the top level - <objects/> element, must be valid XML bean - definitions according to the Spring Schema. + importing file. As you can see, a leading slash is ignored, but given + that these paths are relative, it is better form not to use the slash + at all. The contents of the files being imported, including the top + level <objects/> element, must be valid XML + bean definitions according to the Spring Schema. @@ -452,7 +450,7 @@ [string] you can retrieve instances of your objects. - The IApplicationContext enables you to read + The IApplicationContext enables you to read object definitions and access them as follows: // create and configure beans @@ -484,10 +482,10 @@ IList userList = service.GetUserNames(); - The Objects + Object definition overview A Spring IoC container manages one or more objects. These objects - are created using the configuration metadata that you supply to the + are created with the configuration metadata that you supply to the container. Within the container itself, these object definitions are @@ -520,9 +518,9 @@ IList userList = service.GetUserNames(); - The preceeding concepts translate directly to a set of properties - that eacdh object definition consists of. The following table lists some - of these properties, with links to documentation + This metadata translates to a set of properties that make up each + object definition. The following table lists some of these properties, + with links to documentation
Object definition explanation @@ -532,7 +530,7 @@ IList userList = service.GetUserNames(); - Feature + Property More info @@ -598,14 +596,22 @@ IList userList = service.GetUserNames();
- Besides object definitions which contain information on how to - create a specific object, certain IObjectFactory - implementations also permit the registration of existing objects that - have been created outside the factory (by user code). The - DefaultListableObjectFactory class supports this - through the RegisterSingleton(..) method. (Typical - applications solely work with objects defined through metadata object - definitions though.) + In addition to object definitions which contain information on how + to create a specific object, the + IApplicationContext implementations also permit + the registration of existing objects that are created outside the + container, by users. This is done by accessing the + ApplicationContext's + IObjectFactory via the property + ObjectFactory which returns the + IObjectFactory implementation + DefaultListableObjectFactory. + DefaultListableObjectFactory supports + registration through the methods + RegisterSingleton(..) and + RegisterObjectDefinition(..). However, typical + applications work soley with objects defined through metadata object + definitions. Naming objects @@ -643,10 +649,12 @@ IList userList = service.GetUserNames(); (;), or whitespace.
- You are not required to supply a name for a object. If no name - is supplied explicitly, the container will generate a unique name - for that object. The motivations for not supplying a name for a - object are to use You are not required to supply a name or id for a object. If + no name or id is supplied explicitly, the container will generate a + unique name for that object. However, if you want to refer to that + object by name, through the use of the ref element or Service + Location style lookup, you must provide a name. The motivations for + not supplying a name for a object are to use autowiring and inline-objects which will be discussed later. @@ -675,8 +683,8 @@ IList userList = service.GetUserNames(); <alias name="fromName" alias="toName"/> In this case, an object in the same container which is named - 'fromName', may also after the use of this alias - definition, be referred to as 'toName'. + fromName, may also after the use of this alias + definition, be referred to as toName.
For example, the configuration metadata for subsystem A may refer to a DbProvider via the name 'SubsystemA-DbProvider. The @@ -707,12 +715,12 @@ IList userList = service.GetUserNames(); definition to create (or acquire) an actual object. If you are using XML-based configuration metadata, you can specify - the type of object that is to be instantiated using the + the type of object that is to be instantiated in the 'type' attribute of the <object/> element. This 'type' attribute (which internally is a Type property on a - IObjectDefinition instance) is normally mandatory. + IObjectDefinition instance) is usually mandatory. (For exceptions see the section called Instantiation using an instance factory method and - To specify the type of of the object to be constructed in the - common case where the container itself directly creates the object - by calling its constructor reflectively, somewhat equivalent to C# - code using the 'new' operator. + Typically, to specify the type of of the object to be + constructed in the case where the container itself directly creates + the object by calling its constructor reflectively, somewhat + equivalent to C# code using the 'new' + operator. - In the less common case where the container invokes a - static, factory method on a - class to create the object, specify the actual class containing the - static factory method that is to be invoked to - create the object. The type of the object returned from the - invocation of the static factory method may be - the same type or another type entirely. + To specify the actual class containing the + static factory method that will be invoked to + create the object, in the less common case where the container + invokes a static factory + method on a class to create the object. The object type returned + from the invocation of the static factory method + may be the same type or another type entirely. - Instantiatoin using a constructor + Instantiatoin with a constructor - When you createn an object using the constructor approach, all + When you create an object using the constructor approach, all normal classes are usable by and compatible with Spring. That is, the - type being created does not need to implement any specific interfaces - or be coded in a specific fashion. Just specifying the object type - should be enough. However, depending on what type of IoC you are going - to use for that specific object, you may need to create a default - constructor. + class being developed does not need to implement any specific + interfaces or to be coded in a specific fashion. Simply specifying the + object type should be sufficient. However, depending on what type of + IoC you are going to use for that specific object, you may need to + create a default constructor. With XML-based configuration metadata you can specify your object class as follows: <object id="exampleObject" type="Examples.ExampleObject, ExamplesLibrary"/> - The mechanism for supplying arguments to the constructor (if - required), or setting properties of the object instance after it has - been constructed, is described in + For details about the mechanism for supplying arguments to the + constructor (if required), and setting object instance properties + after the object is constructed, see . This XML fragment describes an object definition that will be identified by the exampleObject name, instances @@ -805,30 +814,29 @@ IList userList = service.GetUserNames(); - Object creation via a static factory method + Instantiation with a static factory method When defining an object which is to be created using a static factory method, you use the type attribute to specify the type containing the static factory method and an attribute named factory-method to specify the name of the factory method itself. You should be able to call this method (with an optional list of arguments - as described later) and return a live object, which from that point on - is treated as if it had been created normally via a constructor. One - use for such an object definition is to call static factories in - legacy code. + as described later) and return a live object, which subsequently is + treated as if it had been created through a constructor. One use for + such an object definition is to call static factories in legacy + code. - The following example shows an object definition that specifies - the object is to be created by calling a factory-method. The - definition does not specify the type of the returned object, only the - type containing the factory method. In this example, - CreateInstance must be a static method. - <object id="exampleObject" + The following object definition specifies that the object will + be created by calling a factory-method. The definition does not + specify the type of the returned object, only the type containing the + factory method. In this example, CreateInstance + must be a static method. <object id="exampleObject" type="Examples.ExampleObjectFactory, ExamplesLibrary" factory-method="CreateInstance"/> - The mechanism for supplying (optional) arguments to the factory - method, or setting properties of the object instance after it has been - returned from the factory, is described in For details about the mechanism for supplying (optional) + arguments to the factory method and setting object instance properties + after it has been returned from the factory, see @@ -837,16 +845,15 @@ IList userList = service.GetUserNames(); Similar to instantiation through a static factory - method, instantiation with an instance factory method involves - the invocation of a non-static method on an existing object from the - container to create a new object. To use this mechanism, leave the - 'type' attribute empty, and in the - 'factory-object' attribute specify the name of an - object in the current (or parent/ancestor) container that contains the - instance method that is to be invoked to create the object. Set the - name of the factory method itself with the - 'factory-method' attribute.<!-- the factory object, which contains an instance method called 'CreateInstance' --> + method, instantiation with an instance factory method invokes a + a non-static method on an existing object from the container to create + a new object. To use this mechanism, leave the type + attribute empty, and in the factory-object + attribute specify the name of an object in the current (or + parent/ancestor) container that contains the instance method that is + to be invoked to create the object. Set the name of the factory method + itself with the factory-method + attribute.<!-- the factory object, which contains an instance method called 'CreateInstance' --> <object id="exampleFactory" type="..."> <!-- inject any dependencies required by this object --> </object> @@ -856,11 +863,10 @@ IList userList = service.GetUserNames(); factory-method="CreateInstance" factory-object="exampleFactory"/> - Although the mechanisms for setting object - properties are still to be discussed, one implication of this - approach is that the factory object itself can be managed and - configured through Dependency Injection (DI). + This approach shows that the factory object itself can be + managed and configured through dependency injection (DI). See Dependencies and + configuraiton in detail. In Spring documentation, 'factory object', refers to an object that is configured in the Spring container that will create objects via an - Injecting dependencies + Dependency injection Dependency injection (DI) is a process whereby objects define their dependencies, that is, the other objects they work with, only @@ -1032,10 +1038,11 @@ public class TestGenericObjectFactory special case of providing constructor arguments for the purposes of this description). The container injects these dependencies when it creates the bean. This process is fundamentally the inverse to the case when the - bean itself is controlling the instantiation of its dependencies on its - own by using direct construction of classes, or the Service Locator - pattern. The inverting of this responsibility is why the name Inversion - of Control (IoC) is used to describe the container's actions. + bean itself is controlling the instantiation or location of its + dependencies by using direct construction of classes, or the Service + Locator pattern. The inverting of this responsibility is why the name + Inversion of Control (IoC) is used to describe the container's + actions. Code is cleaner when using DI and decoupling is more effective when objects are provided with their dependencies. The object does not @@ -1051,7 +1058,7 @@ public class TestGenericObjectFactory you class does not know the location of its dependencies these classes also become easier to test, in particular when the dependencies are interfaces or abstract base classes allowing for stub or mock - implementation to be used in unit tests. + implementation to be used in unit tests. Dependency injection exists in two major variants, Constructor-based dependency injection and Setter-based dependency @@ -1066,8 +1073,8 @@ public class TestGenericObjectFactory construct the object is nearly equivalent, and this discussion treats arguments to a constructor and to a static factory method similarly. The following example shows a class that can only be - dependency-injected by using constructor injection. Notice that there - is nothing special about this class (no container specific interfaces, + dependency-injected with constructor injection. Notice that there is + nothing special about this class (no container specific interfaces, base classes or attributes) public class SimpleMovieLister @@ -1092,8 +1099,8 @@ public class TestGenericObjectFactory argument's type. If ambiguity exists in the constructor arguments of a object definition, then the order in which the constructor arguments are defined in a object definition is the order in which - those arguments will be supplied to the appropriate constructor when - it is being instantiated. Consider the following class: + those arguments are supplied to the appropriate constructor when the + object being instantiated. Consider the following class: namespace X.Y { @@ -1106,24 +1113,24 @@ public class TestGenericObjectFactory } } - No ambiguity exists, assuming of course that Bar and Baz - classes are not related by inheritance. Thus the following + No potential ambiguity exists, assuming of course that Bar and + Baz classes are not related by inheritance. Thus the following configuration will work just fine, and you do not need to specify the constructor argument indexes and / or types explicitly in the - contructor-arg element. + <contructor-arg/> element. - <object name="Foo" type="X.Y.Foo, Example"> - <constructor-arg> - <object type="X.Y.Bar, Example"/> - </constructor-arg> - <constructor-arg> - <object type="X.Y.Baz, Example"/> - </constructor-arg> - </object> + <object id="foo" type="X.Y.Foo, Example"> + <constructor-arg ref="bar"/> + <constructor-arg ref="baz"/> +</object> + +<object id="bar" type="X.Y.Bar, Example"/> +<object id="baz" type="X.Y.Baz, Example"/> + When another object is referenced, the type is known, and - matching can occur (as was the case with the preceding example). - + matching can occur (as was the case with the preceding + example).
When a simple type is used, such as <value>true<value>, Spring cannot @@ -1296,9 +1303,10 @@ namespace SimpleApp Constructor argument Index - You can specify explicitly the index of constructor - arguments by using the index attribute. For - example: <object name="exampleObject" type="SimpleApp.ExampleObject, SimpleApp"> + Use the index attribute to specify + explicitly the index of constructor arguments. For example: + + <object name="exampleObject" type="SimpleApp.ExampleObject, SimpleApp"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </object>In addition to resolving the ambiguity of @@ -1377,7 +1385,7 @@ namespace SimpleApp The IAppliationContext supports constructor- and setter-based DI for the objects it manages. It also supports setter-based DI after some dependencies have already been supplied via - the constructor approach.. + the constructor approach.. The configuration for the dependencies comes in the form of the IObjectDefinition class, which is used together @@ -1496,7 +1504,7 @@ namespace SimpleApp - Examples of Dependency Injection + Examples of dependency injection First, an example of using XML-based configuration metadata for setter-based DI. A small part of a Spring XML configuration file @@ -1650,9 +1658,9 @@ public class MixedIocObject Dependencies and configuration in detail - As mentioned in the previous section, object properties and - constructor arguments can be defined as either references to other - managed objects (collaborators), or values defined inline. Spring's + As mentioned in the previous section, you can define object + properties and constructor arguments as either references to other + managed objects (collaborators), or as values defined inline. Spring's XML-based configuration metadata supports sub-element types within its <property/> and <constructor-arg/> elements for this @@ -1668,7 +1676,7 @@ public class MixedIocObject mentioned previously, TypeConverter instances are used to convert these string values from a System.String to the actual property or argument - type. + type. In the following example, we use a SqlConnection from the @@ -1690,7 +1698,8 @@ public class MixedIocObject The idref element An idref element is simply an error-proof way to pass the - id of another object in the container to a + id (string value - not a reference) of another + object in the container to a <constructor-arg/> or <property/> element.<object id="theTargetObject" type="..."> @@ -1718,13 +1727,13 @@ public class MixedIocObject are only discovered (with ost mikely fatal results) when the 'client' object is actually instantiated. If the 'client' bean is a prototype bean, this typo and the resulting exception may only be - discovered long after the container is deployed. + discovered long after the container is deployed. Additionally, if the reference object is in the same XML unit, - and the object name is the object id, the - local attribute may be used, which will allow the - XML parser itself to validate the object name even earlier, at XML - document parse time. <property name="targetName"> + and the object name is the object id, you can + use the local attribute which allows the XML + parser itself to validate the object name earlier, at XML document + parse time. <property name="targetName"> <idref local="theTargetObject"/> </property> @@ -1749,28 +1758,30 @@ public class MixedIocObject - Referring to collaborating objects + References to other objects (collaborators) The ref element is the final element allowed inside a <constructor-arg/> or - <property/> definition element. You use it to set the - value of the specified property to be a reference to another object - managed by the container (a collaborator). The referenced object is a + <property/> definition element. Here you set the value + of the specified property to be a reference to another object (a + collaborator) managed by the container. The referenced object is a dependency of the object whose property will be set, and it is - initialzed on demand as needed before the property is set. (if it is a - singleton object it may bye initialized already by the container) All - references are ultimately just a reference to another object, but you - can specify the id/name of the other object in three different ways - which determines how scoping and validation is handled. + initialzed on demand as needed before the property is set. (If the + collaborator is a singleton object it may be initialized already by + the container.) All references are ultimately just a reference to + another object. Scoping and validation depend on whether you specify + the id/name of the object through the bean, + local, or parent + attributes. - Specifying the target object by using the + Specifying the target object through the object attribute of the ref tag - is the most general form, and will allows creation of a reference to - any object in the same container (whether or not in the same XML - file), or parent container. The value of the - 'object' attribute may be the same as the - 'id' attribute of the target object, or as one of - the values in the 'name' attribute of the target + is the most general form, and allows creation of a reference to any + object in the same container or parent container, regardless of + whether it is in the same XML file. The value of the + object attribute may be the same as the + id attribute of the target object, or as one of the + values in the name attribute of the target object.<ref object="someObject"/> Specifying the target object by using the @@ -1783,8 +1794,8 @@ public class MixedIocObject about errors are early as possible) if the target object is in the same XML file.<ref local="someObject"/> - Specifying the target object by using the - 'parent' attribute creates a reference to an object + Specifying the target object through the + parent attribute creates a reference to an object that is in a parent container of the current container. The value of the 'parent' attribute may be the same as either the 'id' attribute of the target object, or one of @@ -1800,7 +1811,7 @@ public class MixedIocObject <object id="AccountService" <-- notice that the name of this bean is the same as the name of the 'parent' bean type="Spring.Aop.Framework.ProxyFactoryBean, Spring.Aop"> <property name="target"> - <ref parent="AccountService"/> <-- notice how we refer to the parent bean + <ref parent="AccountService"/> <-- notice how we refer to the parent bean --> </property> <!-- insert other configuration and dependencies as required as here --> </object> @@ -1811,10 +1822,7 @@ public class MixedIocObject An <object/> element inside the <constructor-arg/> or <property/> - element defines so called inner object. An inner object definition - does not need to have any id or name defined, and it is best not to - even specify any id or name value because the id or name value simply - will be ignored by the container. + element defines so called inner object. <object id="outer" type="..."> @@ -1828,11 +1836,13 @@ public class MixedIocObject </property> </object> - In the specific case of inner objects, the 'singleton' flag and - any 'id' or 'name' attribute are effectively ignored. Inner objects - are always anonymous and they are always scoped as prototypes. It is - not possible to inject inner objects into collaborating beans other - than into the enclosing object. + An inner object definition does not require a defined id or + name; the container ignores these values. It also ignores the + scope flag. Inner object are + always anonymous and they are + always scoped as prototypes. It is not possible + to inject inner objects into collaborating beans other than into the + enclosing object. @@ -2023,26 +2033,24 @@ public class MixedIocObject - Setting null values + Null and empty values - The <null> element is used to handle - null values. Spring.NET treats empty arguments for - properties and constructor arguments as empty - string instances. The following configuration - demonstrates this behaviour... + Spring treats empty arguments for properties and the like as + empty Strings. The following XML-based configuration metadata snippet + sets the email property to the empty String value ("") - <object type="Examples.ExampleObject, ExamplesLibrary"> - <property name="email"><value></value></property> - - <!-- equivalent, using value attribute as opposed to nested <value/> element... + <object type="Examples.ExampleObject, ExamplesLibrary"> <property name="email" value=""/> </object> This results in the email property being set to the empty string value (""), in much the same way as can be seen in - the following snippet of C# code... exampleObject.Email = ""; - The special <null/> element may be used to - indicate a null value; to wit... + the following snippet of C# code + + exampleObject.Email = ""; + + The <null> element is used to handle + null values. For example: <object type="Examples.ExampleObject, ExamplesLibrary"> <property name="email"><null/></property> @@ -2050,7 +2058,7 @@ public class MixedIocObject This results in the email property being set to null, again in much the same way as can be seen in - the following snippet of C# code... exampleObject.Email = null; + the following snippet of C# code:exampleObject.Email = null; @@ -2117,6 +2125,10 @@ public class MixedIocObject Value and ref shortcut forms + Spring XML used to be even more verbose. What is now popular + usage is actually the shortcut from of the original way to specify + values and references. + There are also some shortcut forms that are less verbose than using the full value and ref elements. The property, @@ -2184,12 +2196,12 @@ public class MixedIocObject Compound property names and Spring expression references - Note that compound or nested property names are perfectly legal - when setting object properties. Property names are interpreted using - the Spring Expression Language - (SpEL) and therefore can leverage its many features to set property - names. For example, in this object definition a simple nested property - name is configured + You can use compound or nested property names when you set + object properties. Property names are interpreted using the Spring Expression Language (SpEL) and + therefore can leverage its many features to set property names. For + example, in this object definition a simple nested property name is + configured <object id="foo" type="Spring.Foo, Spring.Foo"> <property name="bar.baz.name" value="Bingo"/> @@ -2373,27 +2385,26 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList Using <literal>depends-on</literal> - For most situations, the fact that an object is a dependency of - another is expressed by the fact that one object is set as a property of - another. This is typically accomploished with the - <ref/> element in XML-based configuration - metadata. For the relatively infrequent situations where dependencies - between objects are less direct (for example, when a static initializer - in a class needs to be triggered) the 'depends-on' - attribute may be used to explicitly force one or more objects to be - initialized before the object using this element is initialized. Find - below an example of using the 'depends-on' attribute - to express a dependency on a single object.. <object id="objectOne" type="Examples.ExampleObject, ExamplesLibrary" depends-on="manager"> + If an object is a dependency of another that usually means that + one object is set as a property of another. Typically you accomplish + this with the <ref/> element in XML-based + configuration metadata. However, sometimes dependencies between beans + are less direct; for example, a static initializer in a class needs to + be triggered, such as device driver registration. The + depends-on attribute can explicitly force one or more + beans to be initialized before the bean using this element is + initialized. The following example uses the + depends-on attribute to express a dependency on a + single object: <object id="objectOne" type="Examples.ExampleObject, ExamplesLibrary" depends-on="manager"> <property name="manager" ref="manager"/> </object> <object id="manager" type="Examples.ManagerObject, ExamplesLibrary"/> - If you need to express a dependency on multiple objects, you can - supply a list of object names as the value of the - 'depends-on' attribute, with commas, whitespace and - semicolons all valid delimiters, like so: + To express a dependency on multiple objects, supply a list of + object names as the value of the 'depends-on' + attribute, with commas, whitespace and semicolons used as valid + delimiters: <object id="objectOne" type="Examples.ExampleObject, ExamplesLibrary" depends-on="manager,accountDao"> <property name="manager" ref="manager" /> @@ -2403,67 +2414,55 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList <object id="accountDao" type="Examples.AdoAccountDao, ExamplesLibrary" /> - The 'depends-on' attribute and property is - used not only to specify an initialization time dependency, but also - to specify the corresponding destroy time dependency (in the case of - singleton objects only). Dependent objects that are defined in the - 'depends-on' attribute will be destroyed after the relevant object - itself is destroyed. This thus allows you to control shutdown order - too + The depends-on attribute in the object + definition can specify both an initialization time dependency and, in + the case of a singleton object only, a corresponding destroy time + dependency. Dependent objects that define a + depends-on relationship with a given object are + destroyed first, prior to the given object itself being destroyed. + Thus depends-on can also control shutdown + order. - Lazily-instantiated objects + Lazily-initialized objects - The default behavior for IApplicationContext - implementations is to eagerly pre-instantiate all singleton objects at - startup. Pre-instantiation means that an - IApplicationContext will eagerly create and configure - all of its singleton objects as part of its initialization process. - Generally this is a good thing, because it means that any errors in the - configuration or in the surrounding environment will be discovered - immediately (as opposed to possibly hours or even days down the - line). + By default, IApplicationContext implementations + eagerly pre-instantiate all singleton objects as part of the + initialization process. Generally this pre-instantiation is desirable, + because errors in configuration or the surrounding environment are + discovered immediately, as opposed to hours or even days later. When + this behavior is not desirable, you can prevent pre-instantiation of a + singleton object by marking the object definition as lazy-initialized. A + lazy-initialized object tells the IoC container to create an object + instance when it is first requested, rather than at startup. - However, there are times when this behavior is not what is wanted. - If you do not want a singleton object to be pre-instantiated when using - an IApplicationContext, you can selectively control - this by marking an object definition as lazy-initialized. A - lazily-initialized object indicates to the IoC container whether or not - an object instance should be created at startup or when it is first - requested. - - When configuring objects via XML, this lazy loading is controlled - by the 'lazy-init'attribute on the + In XML, this behavior is controlled by the + 'lazy-init'attribute on the <object/> element; for example: <object id="lazy" type="MyCompany.ExpensiveToCreateObject, MyApp" lazy-init="true"/> <object name="not.lazy" type="MyCompany.AnotherObject, MyApp"/> - When the above configuration is consumed by an + When the preceding configuration is consumed by an IApplicationContext, the object named - 'lazy' will not be eagerly pre-instantiated when the + lazy is not eagerly pre-instantiated when the IApplicationContext is starting up, whereas the - 'not.lazy' object will be eagerly pre-instantiated. + not.lazy object is eagerly pre-instantiated. - One thing to understand about lazy-initialization is that even - though an object definition may be marked up as being lazy-initialized, - if the lazy-initialized object is the dependency of a singleton object - that is not lazy-initialized, when the - IApplicationContext is eagerly pre-instantiating the - singleton, it will have to satisfy all of the singletons dependencies, - one of which will be the lazy-initialized object! So don't be confused - if the IoC container creates one of the objects that you have explicitly - configured as lazy-initialized at startup; all that means is that the - lazy-initialized object is being injected into a non-lazy-initialized - singleton object elsewhere. + However, when a lazy-initialized bean is a dependency of a + singleton object that is not + lazy-initialized, the + IApplicationContext creates the lazy-initialized + bean at startup, because it must satisfy the singleton's dependencies. + The lazy-initialized bean is injected into a singleton object elsewhere + that is not lazy-initialized. - It is also possible to control lazy-initialization at the - container level by using the - 'default-lazy-init'attribute on the <objects/> - element; for example: + You can also control lazy-initialization at the container level by + using the default-lazy-init attribute on the + <objects/> element; for example: <objects default-lazy-init="true"> <!-- no objects will be pre-instantiated... --> @@ -2637,24 +2636,22 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList Checking for dependencies - Spring.NET has the ability to try to check for the existence of - unresolved dependencies of an object deployed into the container. These - are properties of the object, which do not have actual values set for - them in the object definition, or alternately provided automatically by - the autowiring feature. + The Spring IoC container can check for unresolved dependencies of + an object deployed into the container. When enabling checking for + unresolved dependencies all properties of the object must have an + explicit values set for them in the object definition or have their + values set via autowiring. - This feature is sometimes useful when you want to ensure that all - properties (or all properties of a certain type) are set on an object. - Of course, in many cases an object class will have default values for - many properties, or some properties do not apply to all usage scenarios, - so this feature is of limited use. Dependency checking can also be - enabled and disabled per object, just as with the autowiring - functionality. The default dependency checking mode is to - not check dependencies. Dependency checking can be - handled in several different modes. In XML-based configuration, this is - specified via the dependency-check attribute in an - object definition, which may have the following values. + This feature useful when you want to ensure that all properties + (or all properties of a certain type) are set on an object. An object + often has default values for many properties, or some properties do not + apply to all usage scenarios, so this feature is of limited use. You can + enable dependency checking per object, just as with the autowiring + functionality. The default is not not check + dependencies. In XML-based configuration metadata, you specify + dependency checking via the dependency-check + attribute in an object definition, which may have the following values. +
Dependency checking modes @@ -2674,30 +2671,29 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList none - No dependency checking. Properties of the object which - have no value specified for them are simply not set. + (Default) No dependency checking. Properties of the + object which have no value specified for them are simply not + set. simple - Dependency checking is done for primitive types and - collections (this means everything except - collaborators). + Dependency checking for primitive types and collections + (everything except collaborators). object - Dependency checking is done for collaborators - only. + Dependency checking for collaborators only. all - Dependency checking is done for collaborators, - primitive types and collections. + Dependency checking for collaborators, primitive types + and collections. @@ -2705,30 +2701,27 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList - Method Injection + Method injection - For most users, the majority of the objects in the container will - be singletons. When a singleton object needs to collaborate with (use) + In most application scenarios, most object in the container are + singletons. When a singleton object needs to collaborate with (use) another singleton object, or a non-singleton object needs to collaborate - with another non-singleton object, the typical and common approach of - handling this dependency (by defining one object to be a property of the - other) is quite adequate. There is however a problem when the object - lifecycles are different. Consider a singleton object A which needs to - use a non-singleton (prototype) object B, perhaps on each method - invocation on A. The container will only create the singleton object A - once, and thus only get the opportunity to set its properties once. - There is no opportunity for the container to provide object A with a new - instance of object B every time one is needed. + with another non-singleton object, you typically handle the dependency + by defining one object as a property of the other. A problem arrises + when the object lifecycles are different. Suppose singleton object A + needs to use a non-singleton (prototype) object B, perhaps on each + method invocation on A. The container only creates the singleton object + A once, and thus only get the opportunity to set the properties. The + container cannot provide object A with a new instance of object B every + time one is needed. - One solution to this problem is to forego some inversion of - control. Object A can be made aware of the - container by implementing the - IObjectFactoryAware interface, and use programmatic means to ask - the container via a GetObject("B") call for (a - typically new) object B every time it needs it. Find below an admittedly - somewhat contrived example of this approach + A solution is to forego some inversion of control. You can make object A aware + of the container by implementing the + IApplicationContextAware interface, and by making a GetObject("B") call to the + container ask for (a typically new) object B every time it needs + it. Find below an example of this approach using System.Collections; using Spring.Objects.Factory; @@ -2761,33 +2754,35 @@ namespace Fiona.Apple } } - The above example is generally not a desirable solution since the - business code is then aware of and coupled to the Spring Framework. - Method Injection, a somewhat advanced feature of the Spring IoC - container, allows this use case to be handled in a clean fashion. + The preceding is not desirable, because the business code is aware + of and coupled to the Sring Framework. Method Injection, a somewhat + advanced feature of the Spring IoC container, allows this use case to be + handled in a clean fashion. Lookup Method Injection - Lookup method injection refers to the ability of the container - to override abstract or concrete methods on - container managed objects, to return the result - of looking up another named object in the container. The lookup will - typically be of a prototype object as in the scenario described above. - The Spring framework implements this method injection by a dynamically - generating a subclass overriding the method using the classes in the - System.Reflection.Emit namespace. You can read more - about the motivation for Method Injection in this blog - entry. + Lookup method injection is the ability of the container to + override methods on container managed objects, to + return the result of looking up another named object in the container. + The lookup typically involves a prototype object as in the scenario + described in the preceding section. The Spring framework implements + this method injection by a dynamically generating a subclass + overriding the method using the classes in the + System.Reflection.Emit namespace. - So if you look at the code from the previous code snipped (the - CommandManager class), the Spring container is - going to dynamically override the implementation of the + + You can read more about the motivation for Method Injection in + this blog + entry. + + + Looking at the CommandManager class in the + previous code snippit, you see that the Spring container will + dynamically override the implementation of the CreateCommand() method. Your - CommandManager class is not going to have any - Spring dependencies, as can be seen in this reworked example - below: + CommandManager class will not have any Spring + dependencies, as can be seen in this reworked example below: using System.Collections; @@ -2809,15 +2804,15 @@ namespace Fiona.Apple } In the client class containing the method to be injected (the - CommandManager in this case) the method definition must observe the - following form: + CommandManager in this case) the method to be + injected requires a signature of the following form: <public|protected> [abstract] <return-type> TheMethodName(no-arguments); If the method is abstract, the - dynamically-generated subclass will implement the method. Otherwise, - the dynamically-generated subclass will override the concrete method - defined in the original class. Let's look at an example: + dynamically-generated subclass implements the method. Otherwise, the + dynamically-generated subclass overrides the concrete method defined + in the original class. Let's look at an example: <!-- a stateful object deployed as a prototype (non-singleton) --> <object id="command" class="Fiona.Apple.AsyncCommand, Fiona" singleton="false"> @@ -2830,14 +2825,13 @@ namespace Fiona.Apple </object> The object identified as commandManager will - call its own method CreateCommand whenever it needs - a new instance of the command object. It is - important to note that the person deploying the objects must be - careful to deploy the command object as prototype - (if that is actually what is needed). If it is deployed as a singleton the same - instance of singleShotHelper will be returned each - time! + calls its own method CreateCommand whenever it + needs a new instance of the command object. You + must be careful to deploy the command object as + prototype, if that is actually what is needed. If it is deployed as a + singleton the + same instance of singleShotHelper will be returned + each time. Note that lookup method injection can be combined with Constructor Injection (supplying optional constructor arguments to the @@ -2850,15 +2844,13 @@ namespace Fiona.Apple A less commonly useful form of method injection than Lookup Method Injection is the ability to replace arbitrary methods in a - managed object with another method implementation. Users may safely - skip the rest of this section (which describes this somewhat advanced - feature), until this functionality is actually needed. + managed object with another method implementation. - In an XmlObjectFactory, the - replaced-method element may be used to replace an - existing method implementation with another. Consider the following - class, with a method ComputeValue, which we want to - override: + With XML-based configuration metadata, you can use the + replaced-method element to replace an existing + method implementation with another, for a deployed object. Consider + the following class, with a method ComputeValue, + which we want to override: public class MyValueCalculator { @@ -2901,23 +2893,23 @@ public class ReplacementComputeValue : IMethodReplacer <object id="replacementComputeValue" type="Examples.ReplacementComputeValue, ExampleAssembly"/> - One or more contained arg-type elements - within the replaced-method element may be used to - indicate the method signature of the method being overridden. Note - that the signature for the arguments is actually only needed in the - case that the method is actually overloaded and there are multiple - variants within the class. For convenience, the type string for an - argument may be a substring of the fully qualified type name. For - example, all the following would match + You can use one or more contained arg-type + elements within the replaced-method element to + indicate the method signature of the method being overridden. The + signature for the arguments is necessaryonly if the method is + overloaded and multiple variants exist within the class. For + convenience, the type string for an argument may be a substring of the + fully qualified type name. For example, the following all match System.String. System.String String Str - Since the number of arguments is often enough to distinguish + Because the number of arguments is often enough to distinguish between each possible choice, this shortcut can save a lot of typing, - by just using the shortest string which will match an argument. + by allowing you to typ just the shortest string which will match an + argument type.