Author: hlship
Date: Thu Nov 1 18:10:14 2007
New Revision: 591183
URL: http://svn.apache.org/viewvc?rev=591183&view=rev
Log:
Start work on the Tapestry IoC Cookbook.
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/images/ioc-overview.graffle
(with props)
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/basics.apt
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/index.apt
tapestry/tapestry5/trunk/tapestry-ioc/src/site/resources/images/ioc-overview.png
(with props)
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/images/ioc-overview.graffle
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/images/ioc-overview.graffle?rev=591183&view=auto
==============================================================================
Binary file - no diff available.
Propchange:
tapestry/tapestry5/trunk/tapestry-ioc/src/images/ioc-overview.graffle
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/basics.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/basics.apt?rev=591183&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/basics.apt
(added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/basics.apt Thu
Nov 1 18:10:14 2007
@@ -0,0 +1,145 @@
+ ----
+ Basic Services and Injection
+ ----
+
+Basic Services and Injection
+
+ A good part of the basics is convention: what to name your classes, what
packages to put them in and so forth.
+
+ In many cases, these conventions are just a little stronger: you may have to
do some amount of
+ extra configuration if you choose to go your own way.
+
+* Getting Started
+
+ Like anything else, you want to choose a package for your application, such
as org.example.myapp.
+
+ By convention, services go in a package named "services".
+
+ Module classes are suffixed with "Module".
+
+ Thus, you might start with a module class
org.example.myapp.services.MyAppModule.
+
+* Simple Services
+
+ The simplest services don't have any special configuration or dependencies.
They are defined as services so that
+ they can be shared.
+
+ For example, the
{{{../../apidocs/org/apache/tapestry/ioc/services/PropertyAccess.html}PropertyAccess}}
service
+ is used in multiple places around the framework to access properties of
objects (its a wrapper around
+ the Java Beans Introspector and a bit of reflection). This is defined in the
+
{{{../../apidocs/org/apache/tapestry/ioc/services/TapestryIOCModule.html}TapestryIOCModule}}.
+
+ It's useful to share PropertyAccess, because it does a lot of useful caching
internally.
+
+ The PropertyAccess service is defined inside TapestryIOCModule's bind()
method:
+
++----+
+ public static void bind(ServiceBinder binder)
+ {
+ . . .
+ binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
+ binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class);
+ . . .
+ }
++----+
+
+ This example includes
{{{../../apidocs/org/apache/tapestry/ioc/services/ExceptionAnalyzer.html}ExceptionAnalyzer}},
+ because it has a dependency on PropertyAccess:
+
++----+
+public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
+{
+ private final PropertyAccess _propertyAccess;
+
+ public ExceptionAnalyzerImpl(PropertyAccess propertyAccess)
+ {
+ _propertyAccess = propertyAccess;
+ }
+
+ . . .
+}
++----+
+
+ And that's the essence of Tapestry IoC right there; the bind() plus the
constructor is <all> that's necessary.
+
+* Service Disambiguation
+
+ In the previous example, we relied on the fact that only a single service
implements the PropertyAccess interface.
+ Had more than one done so, Tapestry would have thrown an exception when the
ExceptionAnalyzer service was realized (it isn't
+ until a service is realized that dependencies are resolved).
+
+ That's normally ok; in many situations, it makes sense that only a single
service implement a particular interface.
+
+ But there are often exceptions to the rule, and in those cases, we must
provide more information to
+ Tapestry when a service is defined, and when it is injected, in order to
disambiguate -- to inform Tapestry which
+ particular version of service to inject.
+
+ This example demonstrates a number of ideas that we haven't discussed so
far, so try not to get
+ too distracted by some of the details. One of the main concepts introduced
here is <service builder methods>.
+ These are methods, of a Tapestry IoC Module class, that act as an alternate
way
+ to define a service. You often used a service builder method if you are
doing more than simply instantiating a class.
+
+ A service builder method is a method of a Module, prefixed with the word
"build". This defines a service, and
+ dependency injection occurs on the parameters of the service builder method.
+
+ The Tapestry web framework includes the concept of an "asset": a resource
that may be inside a web application, or packaged
+ inside a JAR. Assets are represented as the type
{{{../../apidcos/org/apache/tapestry/Asset.html}Asset}}.
+
+ In fact, there are different implementations of this class: one for context
resources (part of the web application), the other
+ for classpath resources (packaged inside a JAR). The Asset instances are
created via
+ {{{../../apidocs/org/apache/tapesty/AssetFactory.html}AssetFactory}}
services.
+
+ Tapestry defines two such services, in the
+
{{{../../apidocs/org/apache/tapestry/internal/InternalModule.html}InternalModule}}
(which is part of the internal implementation of Tapestry,
+ as opposed to Tapestry's public APIs).
+
++---+
+ @Marker(ClasspathProvider.class)
+ public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache,
+
+ ClasspathAssetAliasManager aliasManager)
+ {
+ ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceCache,
aliasManager);
+
+ resourceCache.addInvalidationListener(factory);
+
+ return factory;
+ }
+
+ @Marker(ContextProvider.class)
+ public AssetFactory buildContextAssetFactory(ApplicationGlobals globals)
+ {
+ return new ContextAssetFactory(_request, globals.getContext());
+ }
++---+
+
+ Service builder methods are used here for two purposes: For the
ClasspathAssetFactory, we are registering the new service as a
+ listener of events from another service. For the ContextAssetFactory, we
are extracting a value from an injected service and passing
+ <that> to the constructor.
+
+ What's important is that the services are differentiated not just in terms
of their name, but in terms of their <marker annotation>.
+
+ The
{{{../../apidocs/org/apache/tapestry/ioc/annotations/Marker.html}Marker}}
annotation provides the discriminator. When
+ the service type is supplemented with the ClasspathProvider annotation, the
ClasspathAssetFactory is injected. When the
+ service type is supplemented with the ContextProvider annotation, the
ContextAssetFactory is injected.
+
+ Here's an example. Again, we've jumped the gun with this <service
contributor method> (we'll get into the why and how of these later), but
+ you can see how Tapestry is figuring out which service to inject based on
the presence of those annotations:
+
++----+
+ public void contributeAssetSource(MappedConfiguration<String, AssetFactory>
configuration,
+ @ContextProvider
+ AssetFactory contextAssetFactory,
+
+ @ClasspathProvider
+ AssetFactory classpathAssetFactory)
+ {
+ configuration.add("context", contextAssetFactory);
+ configuration.add("classpath", classpathAssetFactory);
+ }
++---+
+
+ This is far from the final word on injection and disambiguation; we'll be
coming back to this concept repeatedly. And in later chapters
+ of the cookbook, we'll also go into more detail about the many other
concepts present in this example. The important part is
+ that Tapestry <primarily> works off the parameter type (at the point of
injection), but when that is insufficient (you'll know ... there will be an
error) you
+ can provide additional information, in the form of annotations, to
straighten things out.
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/index.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/index.apt?rev=591183&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/index.apt
(added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/cookbook/index.apt Thu
Nov 1 18:10:14 2007
@@ -0,0 +1,14 @@
+ ----
+ Tapestry IoC Cookbook
+ ----
+
+Tapestry IoC Cookbook
+
+ Tapestry IoC, though designed specifically for the needs of the Tapestry web
framework, also may be employed as a stand-alone IoC container, separate
+ from the rest of Tapestry.
+
+ Tapestry IoC is a sophisticated tool that takes some experience to use
properly.
+
+ The existing documentation is factually correct, but is designed more as a
reference, rather than giving the big picture.
+
+ The cookbook will show a bit more about how to use Tapestry IoC, using real
examples from the Tapestry code base.
\ No newline at end of file
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/site/resources/images/ioc-overview.png
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/resources/images/ioc-overview.png?rev=591183&view=auto
==============================================================================
Binary file - no diff available.
Propchange:
tapestry/tapestry5/trunk/tapestry-ioc/src/site/resources/images/ioc-overview.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml?rev=591183&r1=591182&r2=591183&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml Thu Nov 1 18:10:14
2007
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2006 The Apache Software Foundation
@@ -15,16 +15,16 @@
limitations under the License.
-->
-<project name="Tapestry IoC">
- <bannerLeft>
- <name>Tapestry 5</name>
+<project name="Tapestry IoC">
+ <bannerLeft>
+ <name>Tapestry 5</name>
<href>http://tapestry.apache.org/tapestry5/</href>
- <src>images/tapestry_banner.gif</src>
- </bannerLeft>
- <bannerRight>
- <name>Apache</name>
- <href>http://www.apache.org</href>
- <src>images/asf_logo_wide.gif</src>
+ <src>images/tapestry_banner.gif</src>
+ </bannerLeft>
+ <bannerRight>
+ <name>Apache</name>
+ <href>http://www.apache.org</href>
+ <src>images/asf_logo_wide.gif</src>
</bannerRight>
<skin>
<groupId>org.apache.tapestry</groupId>
@@ -33,44 +33,50 @@
</skin>
<publishDate format="dd MMM yyyy" />
-
- <body>
+
+ <body>
<head>
<script src="http://www.google-analytics.com/urchin.js"
type="text/javascript"></script>
<script type="text/javascript">_uacct = "UA-400821-1";
urchinTracker();</script>
- </head>
-
+ </head>
+
<menu name="Quick Links">
<item name="Download"
href="http://tapestry.apache.org/download.html"/>
</menu>
-
- <menu name="Tapestry IoC Container">
+
+ <menu name="Tapestry IoC Container">
<item name="Introduction" href="index.html"/>
- <item name="Overview of Tapestry IoC" href="overview.html"/>
- <item name="Modules" href="module.html"/>
- <item name="Services" href="service.html"/>
- <item name="Decorators" href="decorator.html"/>
- <item name="Configuration" href="configuration.html"/>
- <item name="Type Coercion" href="coerce.html"/>
- <item name="Case Insensitivity" href="case.html"/>
- <item name="Symbols" href="symbols.html"/>
- <item name="Starting the Registry" href="run.html"/>
- <item name="Object Providers" href="provider.html"/>
- <item name="Ordering" href="order.html"/>
- <item name="Logging" href="logging.html"/>
- <item name="Startup" href="startup.html"/>
- </menu>
-
- <menu name="Service Builders">
- <item name="Chain Of Command" href="command.html"/>
- <item name="Strategy" href="strategy.html"/>
- <item name="Pipeline" href="pipeline.html"/>
- <item name="Shadow Services" href="shadow.html"/>
- </menu>
-
+ <item name="Overview of Tapestry IoC" href="overview.html"/>
+ <item name="Modules" href="module.html"/>
+ <item name="Services" href="service.html"/>
+ <item name="Decorators" href="decorator.html"/>
+ <item name="Configuration" href="configuration.html"/>
+ <item name="Type Coercion" href="coerce.html"/>
+ <item name="Case Insensitivity" href="case.html"/>
+ <item name="Symbols" href="symbols.html"/>
+ <item name="Starting the Registry" href="run.html"/>
+ <item name="Object Providers" href="provider.html"/>
+ <item name="Ordering" href="order.html"/>
+ <item name="Logging" href="logging.html"/>
+ <item name="Startup" href="startup.html"/>
+ </menu>
+
+
+ <menu name="Service Builders">
+ <item name="Chain Of Command" href="command.html"/>
+ <item name="Strategy" href="strategy.html"/>
+ <item name="Pipeline" href="pipeline.html"/>
+ <item name="Shadow Services" href="shadow.html"/>
+ </menu>
+
+ <menu name="Tapestry IoC Cookbook">
+ <item name="Introduction" href="cookbook/index.html"/>
+ <item name="Basics" href="cookbook/basics.html"/>
+ </menu>
+
<menu ref="reports"/>
</body>
-</project>
+</project>