You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2010/12/13 00:41:29 UTC
svn commit: r1044956 -
/incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml
Author: danhaywood
Date: Sun Dec 12 23:41:28 2010
New Revision: 1044956
URL: http://svn.apache.org/viewvc?rev=1044956&view=rev
Log:
more on the applib documentation
Modified:
incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml
Modified: incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml?rev=1044956&r1=1044955&r2=1044956&view=diff
==============================================================================
--- incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml (original)
+++ incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml Sun Dec 12 23:41:28 2010
@@ -815,28 +815,38 @@ public void setPropertyName(PropertyType
<literal moreinfo="none">@Optional</literal> annotation.</para>
</sect1>
- <sect1>
+ <sect1 id="sec.SizeProperties">
<title>How to specify the size of <classname>String</classname>
properties</title>
- <para>Use the <literal moreinfo="none">@MaxLength</literal> to specify
- the maximum number of characters that may be stored within a
- <classname>String</classname> property.</para>
-
- <para>Use the <literal moreinfo="none">@TypicalLength</literal> to
- specify the typical number of characters that are likely to be stored
- within a <classname>String</classname> property. Viewers are expected
- to use this as a hint as to the size of the field to render for the
- property.</para>
+ <para>Use:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the <literal moreinfo="none">@MaxLength</literal> to specify
+ the maximum number of characters that may be stored within a
+ <classname>String</classname> property.</para>
+ </listitem>
+
+ <listitem>
+ <para>the <literal moreinfo="none">@TypicalLength</literal> to
+ specify the typical number of characters that are likely to be
+ stored within a <classname>String</classname> property. Viewers
+ are expected to use this as a hint as to the size of the field to
+ render for the property.</para>
+ </listitem>
- <para>Use the <literal moreinfo="none">@MultiLine</literal> annotation
- as a hint to indicate that the field should be displayed with multiple
- lines (eg as a text area rather than a text field).</para>
+ <listitem>
+ <para>the <literal moreinfo="none">@MultiLine</literal> annotation
+ as a hint to indicate that the property should be displayed over
+ multiple lines (eg as a text area rather than a text
+ field).</para>
+ </listitem>
+ </itemizedlist>
<para>For example:</para>
<programlisting format="linespecific">public class Ticket {
-
@TypicalLength(50)
@MaxLength(255)
public String getDescription() { ... }
@@ -1004,13 +1014,18 @@ public void setPropertyName(PropertyType
</sect2>
</sect1>
- <sect1>
+ <sect1 id="sec.DisabledProperty">
<title>How to prevent a property from being modified</title>
<para>Preventing the user from modifying a property value is known as
'disabling' the property. Note that this doesn't prevent the property
from being modified programmatically.</para>
+ <para>The mechanism for disabling a property is broadly the same as
+ for disabling a collection (see <xref
+ linkend="sec.DisabledCollection" />) or a collection (see <xref
+ linkend="sec.DisabledCollection" />).</para>
+
<sect2>
<title>Disabling a property permanently</title>
@@ -1038,7 +1053,7 @@ public void setPropertyName(PropertyType
object</title>
<para>As a refinement of the above, a property may be optionally
- hidden using the <classname>@Disabled</classname> annotation based
+ disabled using the <classname>@Disabled</classname> annotation based
on the persistence state of the object:</para>
<itemizedlist>
@@ -1403,13 +1418,13 @@ public class Department {
<title>Specifying the name for a collection</title>
<para>By default the framework will use the collection name itself
- to label the property on the user interface. If you wish to override
- this, use the <literal moreinfo="none">@Named</literal> annotation
- on the collection.</para>
+ to label the collection on the user interface. If you wish to
+ override this, use the <literal moreinfo="none">@Named</literal>
+ annotation on the collection.</para>
<para>For example:</para>
- <programlisting format="linespecific">public class Customer() {
+ <programlisting format="linespecific">public class Customer {
@Named("Placed Orders")
public List<Order> getOrders() { ... }
...
@@ -1427,7 +1442,7 @@ public class Department {
<para>For example:</para>
- <programlisting format="linespecific">public class Customer() {
+ <programlisting format="linespecific">public class Customer {
@DescribedAs("Those orders that have been placed (and possibly shipped) " +
"by this customer given name by which this customer is known")
public List<Order> getOrders() { ... }
@@ -1575,6 +1590,10 @@ public class Department {
<para>Preventing the user from adding to or removing from a collection
is known as 'disabling' the collection.</para>
+ <para>The mechanism for disabling a collection is broadly the same as
+ for disabling a property (see <xref linkend="sec.DisabledProperty" />)
+ or a action (see <xref linkend="sec.DisabledAction" />).</para>
+
<sect2>
<title>Disabling a collection permanently</title>
@@ -1608,7 +1627,7 @@ public class Department {
object</title>
<para>As a refinement of the above, a collection may be optionally
- hidden using the <classname>@Disabled</classname> annotation based
+ disabled using the <classname>@Disabled</classname> annotation based
on the persistence state of the object:</para>
<itemizedlist>
@@ -1832,6 +1851,21 @@ public class Department {
action, unless it represents a property, collection, or another
reserved method defined in this guide.</para>
+ <para>The syntax is:</para>
+
+ <para><programlisting>public void actionName([ValueOrEntityType param] ...)</programlisting></para>
+
+ <para>or</para>
+
+ <para><programlisting>public ReturnType actionName([ValueOrEntityType param] ...)</programlisting></para>
+
+ <para>When a method returns a reference the viewer will attempt to
+ display that object. If the return value is <code>null</code> then
+ nothing is displayed.</para>
+
+ <para>We refer to all methods that are intended to be invoked by users
+ as 'action methods'.</para>
+
<para>If you have a method that you don't want to be made available as
a user-action you can either:</para>
@@ -1854,37 +1888,53 @@ public class Department {
<para>Note also that <literal moreinfo="none">static</literal> methods
are ignored: such functionality should reside in a service, such as a
- Repository or Factory.</para>
+ repository or factory (see <xref
+ linkend="chp.RepositoriesAndFactories" />).</para>
+ </sect1>
- <para>We refer to all methods that are intended to be invoked by users
- as 'action methods'.</para>
+ <sect1>
+ <title>How to specify names and/or description for an action</title>
- <para>The syntax is:</para>
+ <sect2>
+ <title>Specifying the name for an action</title>
- <para><programlisting>public void actionName([ValueOrEntityType param] ...)</programlisting></para>
+ <para>By default the framework will use the action name itself to
+ label the menu item on the user interface. If you wish to override
+ this, use the <literal moreinfo="none">@Named</literal> annotation
+ on the action.</para>
- <para>or</para>
+ <para>For example:</para>
- <para><programlisting>public ReturnType actionName([ValueOrEntityType param] ...)</programlisting></para>
+ <programlisting format="linespecific">public class Customer {
+ @Named("Place Order")
+ public void createOrder() { ... }
+ ...
+}</programlisting>
+ </sect2>
- <para>When a method returns a reference the viewer will attempt to
- display that object. If the return value is <code>null</code> then
- nothing is displayed.</para>
- </sect1>
+ <sect2>
+ <title>Specifying a description for a collection</title>
- <sect1>
- <title>How to specify names and/or description for an action</title>
+ <para>An additional description can be provided on an action using
+ the <literal moreinfo="none">@DescribedAs</literal> annotation. The
+ framework will take responsibility to make this description
+ available to the user, for example in the form of a tooltip.</para>
- <para></para>
+ <para>For example:</para>
+
+ <programlisting format="linespecific">public class Customer {
+ @DescribedAs("Places an order, causing a shipping note "+
+ "to be generated and invoice to be dispatched")
+ public void createOrder() { ... }
+ ...
+}</programlisting>
+ </sect2>
</sect1>
<sect1>
<title>How to specify the order in which actions appear on the
menu</title>
- <para>Use the <literal moreinfo="none">@MemberOrder</literal>
- annotation.</para>
-
<para>The <literal moreinfo="none">@MemberOrder</literal> annotation
provides a hint to the viewer as to the order in which the actions
should be displayed, eg in a menu.</para>
@@ -1905,7 +1955,7 @@ public class Department {
<sect1 id="sec.HiddenActions">
<title>How to hide an action</title>
- <para>The mechanism for hiding a property is broadly the same as for
+ <para>The mechanism for hiding an action is broadly the same as for
hiding a property (see <xref linkend="sec.HiddenProperty" />) or a
collection (see <xref linkend="sec.HiddenCollection" />).</para>
@@ -1993,22 +2043,38 @@ public class Department {
</sect2>
</sect1>
- <sect1>
+ <sect1 id="sec.DisabledAction">
<title>How to prevent an action from being invoked</title>
- <sect2>
- <title>*** Always</title>
+ <para>Preventing the user from invoking an action is known as
+ 'disabling' the action.</para>
- <para></para>
+ <para>The mechanism for disabling an action is broadly the same as for
+ disabling a property (see <xref linkend="sec.DisabledProperty" />) or
+ a collection (see <xref linkend="sec.DisabledCollection" />).</para>
+
+ <sect2>
+ <title>Disabling an action permanently</title>
+
+ <para>It is possible to prevent an action from ever being invoked
+ using the <classname>@Disabled</classname> annotation, exactly
+ equivalent to the use of the annotation for properties and
+ collections. However, it's not a particularly meaningful usecase:
+ why display an action that can never be invoked? The only reason we
+ can think of is as a placeholder during prototyping - to indicate to
+ the user that an action is planned, but has not yet been
+ implemented.</para>
</sect2>
<sect2>
<title>Disabling an action based on the persistence state of the
object</title>
- <para>As a refinement of the above, an action may be optionally
- hidden using the <classname>@Disabled</classname> annotation based
- on the persistence state of the object:</para>
+ <para>Whereas annotating an action simply as
+ <classname>@Disabled</classname> probably does not make sense (see
+ above), it does make sense to optionally disable an action using the
+ <classname>@Disabled</classname> annotation based on the persistence
+ state of the object:</para>
<itemizedlist>
<listitem>
@@ -2030,15 +2096,19 @@ public class Department {
be able to initiate the action at all - for example because that
action is not appropriate to the current state of the object on
which the action resides. Such rules are enforced by means of a
- <literal moreinfo="none">disable</literal> method.</para>
+ <literal moreinfo="none">disableXxx()</literal> supporting
+ method.</para>
<para>The syntax is:</para>
- <para><programlisting>public String disable<ActionName>([<parameter type> param]...)</programlisting></para>
+ <para><programlisting>public String disableActionName([ValueOrEntityType param]...)</programlisting></para>
- <para>A non-null return <code>String</code> indicates the reason why
- the action may not be invoked. The framework takes responsibility to
- provide this feedback to the user. For example:</para>
+ <para>A non-<literal>null</literal> return <code>String</code>
+ indicates the reason why the action may not be invoked. The
+ framework takes responsibility to provide this feedback to the user.
+ </para>
+
+ <para>For example:</para>
<programlisting format="linespecific">public class Customer {
public Order placeOrder(Product p, int quantity) { ... }
@@ -2046,13 +2116,9 @@ public class Department {
return isBlackListed()?
"Blacklisted customers cannot place orders"
:null;
- }</programlisting>
-
- <para>It is also possible to permanently disable an action using the
- <literal moreinfo="none">@Disabled</literal> annotation. One
- possible reason for doing this might be during prototyping - to
- indicate to the user that an action is planned, but has not yet been
- implemented.</para>
+ }
+ ...
+}</programlisting>
</sect2>
<sect2>
@@ -2073,27 +2139,78 @@ public class Department {
<para>Unlike with properties, the framework cannot pick up the names
of parameters that you use within the domain code. By default
parameters will be labelled only with the type of the object required
- (e.g. 'String:' or 'Customer:) If you want a parameter to have a
- different name (such as 'First Name', 'Last Name') then that parameter
- should be marked up with an <literal moreinfo="none">@Named</literal>
- annotation - very often taking the same form as the parameter name
- used in the code. (This is one of the few forms of duplication that we
- cannot eliminate; the parameter name is not available in the class'
- bytecode and so cannot be inferred automatically. Alternatively
- though, you could create a user-defined value type, using
- <literal>@Value</literal>).</para>
+ (e.g. 'String:' or 'Customer:)</para>
+
+ <para>If you want a parameter to have a different name (such as 'First
+ Name', 'Last Name') then that parameter should be marked up with an
+ <literal moreinfo="none">@Named</literal> annotation - very often
+ taking the same form as the parameter name used in the code.
+ Alternatively though, you could create a user-defined value type,
+ using <literal>@Value</literal> (see <xref
+ linkend="sec.ValueTypes" />).</para>
<para>Similarly, any parameter may be given a short user-description
using the <literal moreinfo="none">@DescribedAs</literal> annotation.
The framework takes responsibility to make this available to the
user.</para>
+
+ <para>For example:</para>
+
+ <programlisting format="linespecific">public class Customer {
+ public Order placeOrder(
+ Product p,
+ @Named("Quantity")
+ @DescribedAs("The number of units of the specified product in this order")
+ int quantity) {
+ ...
+ }
+ ...
+}</programlisting>
</sect1>
<sect1>
<title>How to specify the size of <classname>String</classname> action
parameters</title>
- <para></para>
+ <para>As for properties (see <xref linkend="sec.SizeProperties" />),
+ use:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the <literal moreinfo="none">@MaxLength</literal> to specify
+ the maximum number of characters that may be stored within a
+ <classname>String</classname> parameter.</para>
+ </listitem>
+
+ <listitem>
+ <para>the <literal moreinfo="none">@TypicalLength</literal> to
+ specify the typical number of characters that are likely to be
+ stored within a <classname>String</classname> parameter. Viewers
+ are expected to use this as a hint as to the size of the field to
+ render for the parameter.</para>
+ </listitem>
+
+ <listitem>
+ <para>the <literal moreinfo="none">@MultiLine</literal> annotation
+ as a hint to indicate that the parameter should be displayed over
+ multiple lines (eg as a text area rather than a text
+ field).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For example:</para>
+
+ <programlisting format="linespecific">public class TicketRaiser {
+
+ public void raiseTicket(
+ @TypicalLength(50) @MaxLength(255) @Named("Description")
+ String getDescription,
+ @MaxLength(2048) @MultiLine @Named("Notes")
+ String notes) {
+ ...
+ }
+ ...
+}</programlisting>
</sect1>
<sect1>
@@ -2108,22 +2225,63 @@ public class Department {
<sect1>
<title>How to validate an action parameter argument</title>
- <para>Use the <literal moreinfo="none">@MaxLength</literal>, <literal
- moreinfo="none">@TypicalLength</literal>, <literal
- moreinfo="none">@MultiLine</literal>, <literal
- moreinfo="none">@Mask</literal> or <literal
- moreinfo="none">@RegEx</literal> annotations.</para>
-
<sect2>
<title>Declarative validation</title>
- <para></para>
+ <para>For parameters that accept a text input string, such as
+ <code>String</code> and <code>Date</code>, there are convenient
+ mechanisms to validate and/or normalise the values typed in:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>For <literal moreinfo="none">Date</literal> and number
+ values the <literal moreinfo="none">@Mask</literal> annotation
+ may be used.</para>
+ </listitem>
+
+ <listitem>
+ <para>For <literal moreinfo="none">String</literal> parameters
+ the <literal moreinfo="none">@RegEx</literal> annotation may be
+ used.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>More complex validation can also be performed imperatively
+ (below).</para>
</sect2>
<sect2>
<title>Imperative validation</title>
- <para></para>
+ <para>A <literal moreinfo="none">validateXxx()</literal> method is
+ used to check that the set of arguments used by an action method is
+ valid. If the arguments are invalid then the framework will not
+ invoke the action.</para>
+
+ <para>The syntax is:</para>
+
+ <para><programlisting>public String validate<ActionName>([ValueOrEntityType param]...)</programlisting></para>
+
+ <para>A non-<code>null</code> return <classname>String</classname>
+ indicates the reason why the member cannot be modified/action be
+ invoked, and the viewing mechanism will display this feedback to the
+ user.</para>
+
+ <para>For example:</para>
+
+ <programlisting format="linespecific">public class Customer {
+ public Order placeOrder(Product p, int quantity) { ... }
+ public String validatePlaceOrder(Product p, int quantity) {
+ if (p.isOutOfStock()) { return "Product is out of stock"; }
+ if (quantity <= 0) { return "Quantity must be a positive value"; }
+ return null;
+ }
+ ...
+}</programlisting>
+
+ <para>For complex validation, you may wish to use the
+ <classname>org.apache.isis.applib.util.ReasonBuffer</classname>
+ helper class.</para>
</sect2>
</sect1>
@@ -2134,48 +2292,69 @@ public class Department {
be provided for any or all of its parameters.</para>
<para>There are two different ways to specify parameters; either per
- parameter, or for all parameters. The per-parameter form is simpler
- and probably preferred; the syntax is:</para>
+ parameter, or for all parameters.</para>
- <programlisting>public <parameter type> defaultN<ActionName>()</programlisting>
+ <sect2>
+ <title>Per-parameter syntax (preferred)</title>
- <para>where N indicates the 0-based parameter number. For
- example:</para>
+ <para>The per-parameter form is simpler and generally to be
+ preferred.</para>
- <programlisting format="linespecific">public class Customer {
+ <para>The syntax is:</para>
+
+ <programlisting>public ParameterType defaultNActionName()</programlisting>
+
+ <para>where N indicates the 0-based parameter number. For
+ example:</para>
+
+ <programlisting format="linespecific">public class Customer {
public Order placeOrder(
- Product product,
- @Named("Quantity")
- int quantity) {
+ Product product,
+ @Named("Quantity")
+ int quantity) {
...
}
public Product default0PlaceOrder() {
return productMostRecentlyOrderedBy(this.getCustomer());
}
+ public int default1PlaceOrder() {
+ return 1;
+ }
}</programlisting>
+ </sect2>
- <para>The syntax for specifying all the parameter default values in
- one go is:</para>
+ <sect2>
+ <title>All parameters syntax</title>
- <para><programlisting>public Object[] default<ActionName>([<parameter type> param]...)</programlisting></para>
+ <para>The syntax for specifying all the parameter default values in
+ one go is:</para>
- <para>returning an array (which must have one element per parameter in
- the action method signature) of corresponding default values. For
- example:</para>
+ <para><programlisting>public Object[] defaultActionName([ValueOrEntityType param]...)</programlisting></para>
- <programlisting format="linespecific">public class Customer {
+ <para>returning an array which must have one element per parameter
+ in the action method signature of corresponding default
+ values.</para>
+
+ <para>For example:</para>
+
+ <programlisting format="linespecific">public class Customer {
public Order placeOrder(
- Product product,
- @Named("Quantity")
- int quantity) {y
+ Product product,
+ @Named("Quantity")
+ int quantity) {
...
}
public Object[] defaultPlaceOrder(
- Product product,
- int quantity) {
- return new Object[] {productMostRecentlyOrderedBy(this.getCustomer()), 1};
+ Product product,
+ int quantity) {
+ return new Object[] {
+ productMostRecentlyOrderedBy(this.getCustomer()),
+ 1
+ };
}
+ ...
}</programlisting>
+ </sect2>
</sect1>
<sect1>
@@ -2185,85 +2364,80 @@ public class Department {
or all of the parameters of an action. These will be made available to
the user - for example as a drop-down list.</para>
- <para>As for defaults, there are two different ways to specify
- parameters; either per parameter, or for all parameters. The
- per-parameter form is simpler and probably preferred; the syntax
- is:</para>
-
- <programlisting>public List<parameter type> choicesN<ActionName>()</programlisting>
+ <para>If the type of the parameter is annotated with <literal
+ moreinfo="none">@Bounded</literal>, then it is not necessary to
+ specify the choices for that parameter, as the user will automatically
+ be offered the full set to choose from.</para>
- <para>where N indicates the 0-based parameter number. For
- example:</para>
+ <para>If this isn't the case, then - as for defaults - there are two
+ different ways to specify parameters; either per parameter, or for all
+ parameters.</para>
- <programlisting format="linespecific">public class Order {
- public Order placeOrder(
- Product product,
- @Named("Quantity")
- int quantity) {
- ...
- }
+ <sect2>
+ <title>Per parameter syntax (preferred)</title>
- public List<Product> choices0PlaceOrder() {
- return lastFiveProductsOrderedBy(this.getCustomer());
- }
-}</programlisting>
+ <para>The per-parameter form is simpler and generally
+ preferred.</para>
- <para>The alternative mechanism is to supply all the parameter choices
- in one go:</para>
+ <para>The syntax is:</para>
- <para><programlisting>public Object[] choices<ActionName>([<parameter type> param]...)</programlisting></para>
+ <programlisting>public List<ParameterType> choicesNActionName()</programlisting>
- <para>returning an array, which must have one element per parameter in
- the method signature. Each element of the array should itself either
- be an array or a list, containing the set of values representing the
- choices for that parameter, or <literal moreinfo="none">null</literal>
- if there are no choices to be specified for that parameter.</para>
+ <para>where N indicates the 0-based parameter number.</para>
- <para>For example:</para>
+ <para>For example:</para>
- <programlisting format="linespecific">public class Order {
+ <programlisting format="linespecific">public class Order {
public Order placeOrder(
- Product product,
- @Named("Quantity")
- int quantity) {
+ Product product,
+ @Named("Quantity")
+ int quantity) {
...
}
-
- public Object[] choicesPlaceOrder(
- Product product,
- int quantity) {
- return new Object[] {lastFiveProductsOrderedBy(this.getCustomer()).toArray(), null};
+ public List<Product> choices0PlaceOrder() {
+ return lastFiveProductsOrderedBy(this.getCustomer());
}
+ public List<Integer> choices1PlaceOrder() {
+ return Arrays.asList(1,2,3,4,5);
+ }
+ ....
}</programlisting>
-
- <para>(Note that if the type of the property is annotated with
- <literal moreinfo="none">@Bounded</literal>, then it is not necessary
- to specify the choices for that parameter, as the user will
- automatically be offered the full set to choose from.)</para>
+ </sect2>
<sect2>
- <title>How to validate parameter values</title>
+ <title>All parameters syntax</title>
- <para>A <literal moreinfo="none">validate</literal> method is used
- to check that the set of arguments used by an action method is
- valid. If the arguments are invalid then the framework will not
- invoke the action. A non-null return String indicates the reason why
- the member cannot be modified/action be invoked, and the viewing
- mechanism will display this feedback to the user.</para>
+ <para>The alternative mechanism is to supply all the parameter
+ choices in one go:</para>
- <para>The syntax is:</para>
+ <para><programlisting>public Object[] choices<ActionName>([<parameter type> param]...)</programlisting></para>
- <para><programlisting>public String validate<ActionName>([<parameter type> param]...)</programlisting></para>
+ <para>returning an array, which must have one element per parameter
+ in the method signature. Each element of the array should itself
+ either be an array or a list, containing the set of values
+ representing the choices for that parameter, or <literal
+ moreinfo="none">null</literal> if there are no choices to be
+ specified for that parameter.</para>
<para>For example:</para>
- <programlisting format="linespecific">public class Customer {
- public Order placeOrder(Product p, int quantity) { ... }
- public String validatePlaceOrder(Product p, int quantity) {
- if (p.isOutOfStock()) { return "Product is out of stock"; }
- if (quantity <= 0) { return "Quantity must be a positive value"; }
- return null;
- }</programlisting>
+ <programlisting format="linespecific">public class Order {
+ public Order placeOrder(
+ Product product,
+ @Named("Quantity")
+ int quantity) {
+ ...
+ }
+ public Object[] choicesPlaceOrder(
+ Product product,
+ int quantity) {
+ return new Object[] {
+ lastFiveProductsOrderedBy(this.getCustomer()).toArray(),
+ Arrays.asList(1,2,3,4,5)
+ };
+ }
+ ...
+}</programlisting>
</sect2>
</sect1>
</chapter>
@@ -2395,7 +2569,7 @@ void warnUser(String message)</programli
</sect1>
</chapter>
- <chapter>
+ <chapter id="chp.RepositoriesAndFactories">
<title>Repositories, Factories, Services and Values</title>
<abstract>