Update of /cvsroot/springnet/Spring.Net/doc/reference/src
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv27260
Modified Files:
objects.xml
Log Message:
SPRNET-907 - Add Required attribute and RequiredObjectFactoryPostProcessor, allowing to enforce required object properties
Index: objects.xml
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/doc/reference/src/objects.xml,v
retrieving revision 1.119
retrieving revision 1.120
diff -C2 -d -r1.119 -r1.120
*** objects.xml 26 Feb 2008 02:04:32 -0000 1.119
--- objects.xml 2 Apr 2008 18:02:11 -0000 1.120
***************
*** 3878,3883 ****
this registration is effected), for each object instance that is created
by the container, the post-processor will get a callback from the
! container both before any initialization methods (such as the
! <methodname>AfterPropertiesSet</methodname> method of the
<classname>IInitializingObject</classname> interface and any declared
init method) are called, and also afterwards. The post-processor is free
--- 3878,3883 ----
this registration is effected), for each object instance that is created
by the container, the post-processor will get a callback from the
! container both <emphasis>before</emphasis> any initialization methods
! (such as the <methodname>AfterPropertiesSet</methodname> method of the
<classname>IInitializingObject</classname> interface and any declared
init method) are called, and also afterwards. The post-processor is free
***************
*** 3981,3985 ****
<para></para>
! <sect3>
<title>Example: Hello World, IObjectPostProcessor-style</title>
--- 3981,3985 ----
<para></para>
! <sect3 id="object-factory-extension-opp-examples-hw">
<title>Example: Hello World, IObjectPostProcessor-style</title>
***************
*** 4055,4059 ****
program will be:</para>
! <programlisting>INFO - Object 'Spring.IocQuickStart.MovieFinder.TracingObjectPostProcessor' is not eligible for being processed by all IObjectPostProcessors (for example: not eligible for auto-proxying).
Object 'MyMovieFinder' created : Spring.IocQuickStart.MovieFinder.SimpleMovieFinder
Object 'MyMovieLister' created : Spring.IocQuickStart.MovieFinder.MovieLister
--- 4055,4060 ----
program will be:</para>
! <programlisting>INFO - Object 'Spring.IocQuickStart.MovieFinder.TracingObjectPostProcessor' is not eligible for being processed by all IObjectPostProcessors
! (for example: not eligible for auto-proxying).
Object 'MyMovieFinder' created : Spring.IocQuickStart.MovieFinder.SimpleMovieFinder
Object 'MyMovieLister' created : Spring.IocQuickStart.MovieFinder.MovieLister
***************
*** 4062,4065 ****
--- 4063,4150 ----
DEBUG - MovieApp Done.</programlisting>
</sect3>
+
+ <sect3 id="object-factory-extension-opp-examplesrapp">
+ <title>Example: the RequiredAttributeObjectPostProcessor</title>
+
+ <para>Using callback interfaces or annotations in conjunction with a
+ custom IObjectPostProcessor implementation is a common means of
+ extending the Spring IoC container. The <literal>[Required]</literal>
+ attribute in the <literal>Spring.Objects.Factory.Attributes</literal>
+ namespace can be used to <emphasis>mark</emphasis> a property as
+ being<emphasis> 'required-to-be-set' </emphasis>(i.e. an setter
+ property with this attribute applied must be configured to be
+ dependency injected with a value), else an
+ <classname>ObjectInitializationException</classname> will be thrown by
+ the container at runtime.</para>
+
+ <para>The best way to illustrate the usage of this attribute is with
+ an example.</para>
+
+ <programlisting>public class MovieLister
+ {
+ // the MovieLister has a dependency on the MovieFinder
+ private IMovieFinder _movieFinder;
+
+ // a setter property so that the Spring container can 'inject' a MovieFinder
+ [Required]
+ public IMovieFinder MovieFinder
+ {
+ set { _movieFinder = value; }
+ }
+
+ // business logic that actually 'uses' the injected MovieFinder is omitted...
+
+ }</programlisting>
+
+ <para>Hopefully the above class definition reads easy on the eye. Any
+ and all <literal>IObjectDefinitions</literal> for the
+ <classname>MovieLister</classname> class must be provided with a
+ value.</para>
+
+ <para>Let's look at an example of some XML configuraiton that will not
+ pass validation.</para>
+
+ <programlisting> <object id="MyMovieLister"
+ type="Spring.IocQuickStart.MovieFinder.MovieLister, Spring.IocQuickStart.MovieFinder">
+ <!-- whoops, no MovieFinder is set (and this property is [Required]) -->
+ </object></programlisting>
+
+ <para>At runtime the following message will be generated by the Spring
+ container</para>
+
+ <programlisting>Error creating context 'spring.root': Property 'MovieFinder' required for object 'MyMovieLister'</programlisting>
+
+ <para>There is one last little piece of Spring configuration that is
+ required to actually 'switch on' this behavior. Simply annotating the
+ 'setter' properties of your classes is not enough to get this
+ behavior. You need to enable a component that is aware of the
+ <literal>[Required]</literal> attribute and that can process it
+ appropriately.</para>
+
+ <para>This component is the
+ <classname>RequiredAttributeObjectPostProcessor</classname> class.
+ This is a special <literal>IObjectPostProcessor</literal>
+ implementation that is <literal>[Required]</literal>-aware and
+ actually provides the 'blow up if this required property has not been
+ set' logic. It is very easy to configure; simply drop the following
+ object definition into your Spring XML configuration.</para>
+
+ <programlisting><object type="Spring.Objects.Factory.Attributes.RequiredAttributeObjectPostProcessor, Spring.Core"/></programlisting>
+
+ <para>Finally, one can configure an instance of the
+ <classname>RequiredAttributeObjectPostProcessor</classname> class to
+ look for another <literal>Attribute</literal> type. This is great if
+ you already have your own <literal>[Required]</literal>-style
+ attribute. Simply plug it into the definition of a
+ <classname>RequiredAttributeObjectPostProcessor</classname> and you
+ are good to go. By way of an example, let's suppose you (or your
+ organization / team) have defined an attribute called [Mandatory]. You
+ can make a <classname>RequiredAttributeObjectPostProcessor</classname>
+ instance <literal>[Mandatory]</literal>-aware like so: </para>
+
+ <programlisting><object type="Spring.Objects.Factory.Attributes.RequiredAttributeObjectPostProcessor, Spring.Core">
+ <property name="RequiredAttributeType" value="MyApp.Attributes.MandatoryAttribute, MyApp"/>
+ </object></programlisting>
+ </sect3>
</sect2>
***************
*** 4170,4174 ****
<sect3 id="objects-factory-placeholderconfigurer">
! <title>The
<classname>PropertyPlaceholderConfigurer</classname></title>
--- 4255,4259 ----
<sect3 id="objects-factory-placeholderconfigurer">
! <title>Example: The
<classname>PropertyPlaceholderConfigurer</classname></title>
***************
*** 4351,4355 ****
<sect3 id="objects-factory-overrideconfigurer">
! <title>The <classname>PropertyOverrideConfigurer</classname></title>
<para>The <classname>PropertyOverrideConfigurer</classname>, another
--- 4436,4441 ----
<sect3 id="objects-factory-overrideconfigurer">
! <title>Example: The
! <classname>PropertyOverrideConfigurer</classname></title>
<para>The <classname>PropertyOverrideConfigurer</classname>, another
|