I was about to ask the same question. I didn't find a link to it.
On Dec 8, 2010 2:59 AM, "Ulrich Stärk" <[email protected]> wrote:
> Folks,
>
> did I miss something or did we forget to link to the IoC cookbook? I
couldn't find a starting point
> in any of the exported pages.
>
> Uli
>
> On 08.12.2010 02:39, [email protected] wrote:
>>
>> IoC cookbook - patterns
>> <
https://cwiki.apache.org/confluence/display/TAPESTRY/IoC+cookbook+-+patterns
>
>>
>>
>> Page *edited* by Bob Harner <
https://cwiki.apache.org/confluence/display/~bobharner>
>>
>> *Comment:* Added scrollbar at top & bottom, fixed broken link
>>
>>
>> Changes (3)
>>
>> {scrollbar}
>> h1. Using Patterns
>>
>> Tapestry IoC has support for implementing several of the [Gang Of Four
Design
>> Patterns|http://en.wikipedia.org/wiki/Design_pattern_(computer_science)].
In fact, the IoC container
>> itself is a pumped up version of the Factory pattern.
>>
>> The basis for these patterns is often the use of _service builder
methods_, where a
>> [configuration|#servconf.html] [configuration|IoC cookbook - servconf]
for the service is combined
>> with a factory to produce the service implementation on the fly.
>>
>> {anchor:chainofcommand}
>> ...
>>
>> Reducing the chain to a single object vastly simplifies the code:
we've _factored out_ the loop
>> implicit in the chain of command. That eliminates a lot of code, and
that's less code to test,
>> and fewer paths through InjectWorker, which lowers its complexity
further. We don't have to
>> test the cases where the list of injection providers is empty, or
consists of only a single object,
>> or where it's the third object in that returns true: it looks like a
single object, it acts
>> like a single object ... but its implementation uses many objects.
>>
>> {scrollbar}
>>
>>
>> Full Content
>>
>> </confluence/display/TAPESTRY/IoC+cookbook+-+override> IoC cookbook -
override
>> </confluence/display/TAPESTRY/IoC+cookbook+-+override>
^</confluence/display/TAPESTRY/IoC+cookbook>
>> IoC cookbook </confluence/display/TAPESTRY/IoC+cookbook> IoC cookbook -
servconf
>> </confluence/display/TAPESTRY/IoC+cookbook+-+servconf>
>> </confluence/display/TAPESTRY/IoC+cookbook+-+servconf>
>>
>>
>> Using Patterns
>>
>> Tapestry IoC has support for implementing several of the Gang Of Four
Design Patterns
>> <http://en.wikipedia.org/wiki/Design_pattern_(computer_science)>. In
fact, the IoC container itself
>> is a pumped up version of the Factory pattern.
>>
>> The basis for these patterns is often the use of /service builder
methods/, where a configuration
>> </confluence/display/TAPESTRY/IoC+cookbook+-+servconf> for the service is
combined with a factory to
>> produce the service implementation on the fly.
>>
>>
>> Chain of Command Pattern
>>
>> Main Article: Chain of Command
</confluence/display/TAPESTRY/IoC+-+command>
>>
>> Let's look at another example, again from the Tapestry code base. The
InjectProvider
>> <
http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/InjectionProvider.html
>
>> interface is used to process the @Inject annotation on the fields of a
Tapestry page or component.
>> Many different instances are combined together to form a /chain of
command/.
>>
>> The interface has only a single method (this is far from uncommon):
>>
>> public interface InjectionProvider
>> {
>> boolean provideInjection(String fieldName,Class fieldType, ObjectLocator
locator,
>> ClassTransformation transformation, MutableComponentModel
componentModel);
>> }
>>
>> The return type indicates whether the provider was able to do something.
For example, the
>> AssetInjectionProvider checks to see if there's an @Path annotation on
the field, and if so,
>> converts the path to an asset, works with the ClassTransformation object
to implement injection, and
>> returns true to indicate success. Returns true terminates the chain
early, and that true value is
>> ultimately returned to the caller.
>>
>> In other cases, it returns false and the chain of command continues down
to the next provider. If no
>> provider is capable of handling the injection, then the value false is
ultimately returned.
>>
>> The InjectionProvider service is built up via contributions. These are
the contributions from the
>> TapestryModule:
>>
>> public static void contributeInjectionProvider(
>> OrderedConfiguration<InjectionProvider> configuration,
>> MasterObjectProvider masterObjectProvider,
>> ObjectLocator locator,
>> SymbolSource symbolSource,
>> AssetSource assetSource)
>> {
>> configuration.add("Default",new
DefaultInjectionProvider(masterObjectProvider, locator));
>>
>> configuration.add("ComponentResources",new
ComponentResourcesInjectionProvider());
>>
>> configuration.add(
>> "CommonResources",
>> new CommonResourcesInjectionProvider(),
>> "after:Default");
>>
>> configuration.add(
>> "Asset",
>> new AssetInjectionProvider(symbolSource, assetSource),
>> "before:Default");
>>
>> configuration.add("Block",new
BlockInjectionProvider(),"before:Default");
>> configuration.add("Service",new
ServiceInjectionProvider(locator),"after:*");
>> }
>>
>> And, of course, other contributions could be made in other modules ... if
you wanted to add in your
>> own form of injection.
>>
>> The configuration is converted into a service via a service builder
method:
>>
>> public InjectionProvider build(List<InjectionProvider>
configuration, ChainBuilder chainBuilder)
>> {
>> return chainBuilder.build(InjectionProvider.class, configuration);
>> }
>>
>> Now, let's see how this is used. The InjectWorker class looks for fields
with the InjectAnnotation,
>> and uses the chain of command to inject the appropriate value. However,
to InjectWorker, there is no
>> chain ... just a /single/ object that implements the InjectionProvider
interface.
>>
>> public class InjectWorkerimplements ComponentClassTransformWorker
>> {
>> private final ObjectLocator locator;
>>
>> // Really, a chain of command
>>
>> private final InjectionProvider injectionProvider;
>>
>> public InjectWorker(ObjectLocator locator, InjectionProvider
injectionProvider)
>> {
>> this.locator = locator;
>> this.injectionProvider = injectionProvider;
>> }
>>
>> public final void transform(ClassTransformation transformation,
MutableComponentModel model)
>> {
>> for (String fieldName :
transformation.findFieldsWithAnnotation(Inject.class))
>> {
>> Inject annotation = transformation.getFieldAnnotation(fieldName,
Inject.class);
>>
>> try
>> {
>> String fieldType = transformation.getFieldType(fieldName);
>>
>> Class type = transformation.toClass(fieldType);
>>
>> boolean success = injectionProvider.provideInjection(
>> fieldName,
>> type,
>> locator,
>> transformation,
>> model);
>>
>> if (success) transformation.claimField(fieldName, annotation);
>> }
>> catch (RuntimeException ex)
>> {
>> throw new
RuntimeException(ServicesMessages.fieldInjectionError(transformation
>> .getClassName(), fieldName, ex), ex);
>> }
>>
>> }
>> }
>> }
>>
>> Reducing the chain to a single object vastly simplifies the code: we've
/factored out/ the loop
>> implicit in the chain of command. That eliminates a lot of code, and
that's less code to test, and
>> fewer paths through InjectWorker, which lowers its complexity further. We
don't have to test the
>> cases where the list of injection providers is empty, or consists of only
a single object, or where
>> it's the third object in that returns true: it looks like a single
object, it acts like a single
>> object ... but its implementation uses many objects.
>>
>> </confluence/display/TAPESTRY/IoC+cookbook+-+override> IoC cookbook -
override
>> </confluence/display/TAPESTRY/IoC+cookbook+-+override>
^</confluence/display/TAPESTRY/IoC+cookbook>
>> IoC cookbook </confluence/display/TAPESTRY/IoC+cookbook> IoC cookbook -
servconf
>> </confluence/display/TAPESTRY/IoC+cookbook+-+servconf>
>> </confluence/display/TAPESTRY/IoC+cookbook+-+servconf>
>>
>> Change Notification Preferences <
https://cwiki.apache.org/confluence/users/viewnotifications.action>
>> View Online <
https://cwiki.apache.org/confluence/display/TAPESTRY/IoC+cookbook+-+patterns>
| View
>> Changes
>> <
https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=23338499&revisedVersion=7&originalVersion=6
>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>