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 2020/09/22 23:29:24 UTC

[isis] 01/02: ISIS-2222: adds property command to demo

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2222
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 3fdb8511dcf57cf5482c7ef3255dd6cbe7545efc
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Sep 22 23:11:00 2020 +0100

    ISIS-2222: adds property command to demo
    
    and updates some docs on headless access.
---
 .../modules/btb/pages/headless-access.adoc         |  33 ++++--
 .../AbstractIsisSessionTemplate.adoc               |  55 ----------
 .../BackgroundCommandExecution.adoc                |  48 ---------
 .../demoapp/dom/annotDomain/Action/ActionMenu.java |  19 ++--
 .../ActionCommandDisabledMetaAnnotation.java       |   3 +-
 .../ActionCommandEnabledMetaAnnotation.java        |   3 +-
 .../command/ActionCommandJdo-description.adoc      |  13 +--
 .../Action/command/ActionCommandJdo.layout.xml     |   6 +-
 .../dom/annotDomain/Collection/CollectionMenu.java |   2 +
 .../annotDomain/DomainObject/DomainObjectMenu.java |   4 +
 .../dom/annotDomain/Property/PropertyMenu.java     |  22 ++--
 .../PropertyCommandDisabledMetaAnnotation.java}    |  10 +-
 .../PropertyCommandEnabledMetaAnnotation.java}     |  10 +-
 .../command/PropertyCommandJdo-description.adoc}   |  72 +++----------
 .../Property/command/PropertyCommandJdo.java       | 117 +++++++++++++++++++++
 .../command/PropertyCommandJdo.layout.xml}         |   6 +-
 .../command/PropertyCommandJdoEntities.java        |  34 ++++++
 .../command/PropertyCommandJdoSeedService.java}    |   8 +-
 .../PropertyDomainEventControlService.java         |   7 +-
 .../PropertyPublishingJdoSeedService.java          |   9 +-
 .../PropertyLayout/PropertyLayoutMenu.java         |  10 +-
 .../navigable/FileTreeNodeService.java             |   8 +-
 .../src/main/java/demoapp/dom/error/ErrorMenu.java |   4 +-
 .../demoapp/dom/events/DemoEventSubscriber.java    |   6 +-
 .../demoapp/dom/events/EventLogRepository.java     |   9 +-
 .../java/demoapp/dom/events/EventsDemoMenu.java    |   4 +-
 .../apptenancy/entities/TenantedJdoEntities.java   |   7 +-
 .../entities/seed/TenantedJdoSeedService.java      |   8 +-
 .../src/main/java/demoapp/dom/jee/JeeMenu.java     |   4 +-
 .../src/main/java/demoapp/dom/menubars.layout.xml  |   1 +
 .../main/java/demoapp/dom/mixins/MixinMenu.java    |   4 +-
 .../demoapp/dom/mixins/legacy/MixinLegacyMenu.java |   4 +-
 .../WrapperFactoryJdoSeedService.java              |   7 +-
 .../src/main/java/demoapp/dom/tabs/TabMenu.java    |   7 +-
 .../main/java/demoapp/dom/tooltip/TooltipMenu.java |   4 +-
 .../types/isis/blobs/jdo/IsisBlobJdoEntities.java  |   7 +-
 .../isis/blobs/jdo/IsisBlobJdoSeedService.java     |   7 +-
 .../types/isis/clobs/jdo/IsisClobJdoEntities.java  |   7 +-
 .../isis/clobs/jdo/IsisClobJdoSeedService.java     |   7 +-
 .../isis/images/jdo/IsisImageJdoEntities.java      |   8 +-
 .../isis/images/jdo/IsisImageJdoSeedService.java   |   7 +-
 .../jdo/IsisLocalResourcePathJdoEntities.java      |   7 +-
 .../jdo/IsisLocalResourcePathJdoSeedService.java   |   7 +-
 .../isis/markups/jdo/IsisMarkupJdoEntities.java    |   7 +-
 .../isis/markups/jdo/IsisMarkupJdoSeedService.java |   6 +-
 .../command => types/isisschema/chg}/.gitkeep      |   0
 .../command => types/isisschema/cmd}/.gitkeep      |   0
 .../command => types/isisschema/ixn}/.gitkeep      |   0
 .../demo/domain/src/main/resources/application.yml |   3 +
 .../java/demoapp/web}/linebreaker/LineBreaker.java |  12 ++-
 extensions/core/command-replay/secondary/pom.xml   |   2 +
 .../ROOT/partials/security/user-registration.adoc  |   2 +-
 52 files changed, 360 insertions(+), 297 deletions(-)

diff --git a/api/adoc/userguide/modules/btb/pages/headless-access.adoc b/api/adoc/userguide/modules/btb/pages/headless-access.adoc
index 05b31f2..37b1586 100644
--- a/api/adoc/userguide/modules/btb/pages/headless-access.adoc
+++ b/api/adoc/userguide/modules/btb/pages/headless-access.adoc
@@ -6,19 +6,38 @@
 
 This section tackles the topic of enabling access to an Apache Isis application directly, or at least, not through either the xref:vw:ROOT:about.adoc[Wicket] or xref:vro:ROOT:about.adoc[Restful] viewers.
 
-There are several main use-cases:
-
-* enabling background execution, eg of a thread managed by Quartz scheduler and running within the webapp
+There are a number of use-cases:
 
 * integration from other systems, eg for a subscriber on a pub/sub mechanism such as Camel, pushing changes through an Apache Isis domain model.
 
 * leveraging an Apache Isis application within a batch process
 
-Note that the calling thread runs in the same process space as the Apache Isis domain object model (must be physically linked to the JAR files containing the domain classes).  For use cases where the calling thread runs in some other process space (eg migrating data from a legacy system), then the xref:vro:ROOT:about.adoc[Restful Objects viewer] is usually the way to go.
+Note that the calling thread runs in the same process space as the Apache Isis domain object model (must be physically linked to the JAR files containing the domain classes).
+For use cases where the calling thread runs in some other process space (eg migrating data from a legacy system), then the xref:vro:ROOT:about.adoc[Restful Objects viewer] is usually the way to go.
+
+The key to headless access is the `IsisInteractionFactory` service, a singleton managed by Spring.
+Use it as follows:
+
+[source,java]
+----
+@Service
+@lombok.RequiredArgsConstructor(onConstructor_ = { @Inject })
+private static class HeadlessAccess {
 
-The API described in this chapter is reasonably low-level, allowing code to interact very directly with the Apache Isis metamodel and runtime.  Such callers should be considered trusted: they do not (by default) honour any business rules eg implicit in the Isis annotations or hide/disable/validate methods.  However the xref:refguide:applib-svc:WrapperFactory.adoc[`WrapperFactory`] service could be used to enforce such business rules if required.
+    final IsisInteractionFactory isisInteractionFactory;
+    final TransactionService transactionService;
 
+    @Override
+    public R call(AuthenticationSession session, Supplier<R> supplier) {
+        return isisInteractionFactory.callAuthenticated(session, () -> {
+            return transactionService.executeWithinTransaction(() -> {
+                    return supplier.get();
+                });
+        });
+    }
+}
+----
 
+The API described here is reasonably low-level, allowing code to interact very directly with the Apache Isis metamodel and runtime.
+Such callers should be considered trusted: they do not (by default) honour any business rules eg implicit in the Isis annotations or hide/disable/validate methods.
 
-include::headless-access/AbstractIsisSessionTemplate.adoc[leveloffset=+1]
-//include::headless-access/BackgroundCommandExecution.adoc[leveloffset=+1]
diff --git a/api/adoc/userguide/modules/btb/pages/headless-access/AbstractIsisSessionTemplate.adoc b/api/adoc/userguide/modules/btb/pages/headless-access/AbstractIsisSessionTemplate.adoc
deleted file mode 100644
index 57d443b..0000000
--- a/api/adoc/userguide/modules/btb/pages/headless-access/AbstractIsisSessionTemplate.adoc
+++ /dev/null
@@ -1,55 +0,0 @@
-[[AbstractIsisSessionTemplate]]
-= AbstractIsisSessionTemplate
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-The `AbstractIsisSessionTemplate` class (whose name is inspired by the Spring framework's naming convention for similar classes that query http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-JdbcTemplate[JDBC], http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-jmstemplate[JMS], http://docs.spring.io/spring/docs/2.5.x/reference/orm.html#orm-jpa-template[JPA] etc.) provides the mechanism to open up a 'session' within the Apache Isis framework, in order to resolve  [...]
-
-The class itself is intended to be subclassed:
-
-[source,java]
-.AbstractIsisSessionTemplate.java
-----
-public abstract class AbstractIsisSessionTemplate {
-
-    public void execute(                                              // <.>
-            final AuthenticationSession authSession,
-            final Object context) {
-        // ...
-    }
-
-    protected void doExecute(final Object context) {                  // <.>
-        transactionService.executeWithinTransaction(()->{
-            doExecuteWithTransaction(context);
-        });
-    }
-
-    protected void doExecuteWithTransaction(final Object context) {}  // <.>
-}
-----
-<.> `execute(...)` sets up the `IsisSession` and delegates to ...
-<.> `doExecute(...)`, a hook method for subclasses to implement.
-The passed object represents passes a context from the caller (eg the scheduler, cron job, JMS etc) that instantiated and executed the class.
-<.> Alternatively, override the `doExecuteWithTransaction()`.
-
-In fact, the initial `execute(...)` method implementation is simply:
-
-[source,java]
-----
-public void execute(final AuthenticationSession authSession, final Object context) {
-    isisSessionFactory.runAuthenticated(authSession, ()->{
-        serviceInjector.injectServicesInto(this);
-        doExecute(context);
-    });
-}
-----
-
-So, as an alternative to using `AbstractIsisSessionTemplate`, you could instead just use `IsisSessionFactory`.
-
-If you _do_ use `AbstractIsisSessionTemplate`, note that it automatically inject any domain services into itself.
-Thus, it is relatively easy for the subclass to "reach into" the domain, through injected services.
-
-
-
diff --git a/api/adoc/userguide/modules/btb/pages/headless-access/BackgroundCommandExecution.adoc b/api/adoc/userguide/modules/btb/pages/headless-access/BackgroundCommandExecution.adoc
deleted file mode 100644
index d683232..0000000
--- a/api/adoc/userguide/modules/btb/pages/headless-access/BackgroundCommandExecution.adoc
+++ /dev/null
@@ -1,48 +0,0 @@
-= BackgroundCommandExecution
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-WARNING: TODO: v2 - this functionality has been temporarily removed, will be reinstated for v2.0
-
-
-The `BackgroundCommandExecution` class (a subclass of xref:userguide:btb:about.adoc#BackgroundCommandService[`BackgroundCommandService`].
-
-Its signature is:
-
-[source,java]
-----
-public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {
-    protected void doExecute(Object context) { /* ... */ }
-    protected abstract List<? extends Command> findBackgroundCommandsToExecute(); // <1>
-}
-----
-<1> `findBackgroundCommandsToExecute()` is a mandatory hook method for subclasses to implement.
-
-This allows for different implementations of the `CommandService` and `BackgroundCommandService` to persist to wherever.
-
-The diagram below (http://yuml.me/edit/363b335f[yuml.me/363b335f]) shows the dependencies between these various classes:
-
-.Inheritance Hierarchy for `BackgroundCommandExecution`
-image::headless-access/BackgroundCommandExecution.png[width="400px",link="{imagesdir}/headless-access/BackgroundCommandExecution.png"]
-
-
-
-
-
-
-
-== Background Execution
-
-The `BackgroundCommandExecutionFromBackgroundCommandServiceJdo` is a concrete subclass of `BackgroundCommandExecution` (see the xref:refguide:applib-svc:BackgroundService.adoc[`BackgroundCommandService`]), the intended use being for the class to be instantiated regularly (eg every 10 seconds) by a scheduler such as http://quartz-scheduler.org[Quartz]) to poll for ``Command``s to be executed, and then execute them.
-
-This implementation queries for ``Command``s persisted by thexref:extensions:command-log:about.adoc[Command Log] extension's implementations of xref:refguide:applib-svc:CommandService.adoc[`CommandService`].
-
-//and xref:refguide:applib-svc:BackgroundCommandService.adoc[`BackgroundCommandService`] using the `BackgroundCommandServiceJdoRepository`.
-
-The diagram below (link:http://yuml.me/edit/25343da1[yuml.me/25343da1]) shows the inheritance hierarchy for this class:
-
-.Inheritance Hierarchy for `BackgroundCommandExecutionFromBackgroundCommandServiceJdo`
-image::headless-access/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.png[width="500px",link="{imagesdir}/headless-access/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.png"]
-
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/ActionMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/ActionMenu.java
index 14c7cde..616d770 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/ActionMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/ActionMenu.java
@@ -18,9 +18,6 @@
  */
 package demoapp.dom.annotDomain.Action;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
@@ -29,6 +26,7 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -43,13 +41,16 @@ import demoapp.dom.annotDomain.Action.publishing.ActionPublishingJdo;
 import demoapp.dom.annotDomain.Action.publishing.ActionPublishingJdoEntities;
 import demoapp.dom.annotDomain.Action.typeOf.ActionTypeOfVm;
 import demoapp.dom.annotDomain.Action.typeOf.child.ActionTypeOfChildVm;
-import demoapp.dom.annotDomain.Property.publishing.PropertyPublishingJdo;
-import demoapp.dom.types.Samples;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.ActionMenu")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class ActionMenu {
 
+    final ActionCommandJdoEntities actionCommandJdoEntities;
+    final ActionPublishingJdoEntities actionPublishingJdoEntities;
+    final NameSamples samples;
+
     @Action(semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa="fa-ring", describedAs = "Semantic relationship between actions and other properties or collections")
     public ActionAssociateWithVm associateWith(){
@@ -106,13 +107,5 @@ public class ActionMenu {
         return typeOfVm;
     }
 
-    @Inject
-    ActionPublishingJdoEntities actionPublishingJdoEntities;
-
-    @Inject
-    ActionCommandJdoEntities actionCommandJdoEntities;
-
-    @Inject
-    NameSamples samples;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java
index fd271ba..6b89389 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java
@@ -7,9 +7,10 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.CommandReification;
 
 //tag::class[]
-@Action()                                       // <.>
+@Action(command = CommandReification.DISABLED)  // <.>
 @Inherited
 @Target({
         ElementType.TYPE, ElementType.METHOD    // <.>
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java
index 62e0d52..b62542f 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java
@@ -7,10 +7,11 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.CommandReification;
 import org.apache.isis.applib.annotation.Publishing;
 
 //tag::class[]
-@Action(publishing = Publishing.ENABLED)        // <.>
+@Action(command = CommandReification.ENABLED)   // <.>
 @Inherited
 @Target({
         ElementType.TYPE, ElementType.METHOD    // <.>
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc
index e3f3ad6..cfbff5f 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc
@@ -1,17 +1,18 @@
-The `command` semantic is used to allow or suppress the reification of an action invocation or property edit into a `Command`.
+The `command` semantic is used to allow or suppress the reification of an action invocation into a `Command`.
 
 When allowed (the default), then the `Command` is sent to registered implementation(s) of https://isis.apache.org/refguide/2.0.0-M3/applib-svc/CommandServiceListener.html#section-top[`CommandServiceListener`] SPI, _after_ the interaction has completed.
 One use case is to replicate and replay commands to a secondary system, for example for regression testing.
-For more on this, see "Command Replay" section below.
+For more on this, see the "Command Replay" section below.
 
-Commands are also used under the covers to allow actions/edits to be called asynchronously using the link:https://isis.apache.org/refguide/2.0.0-M3/applib-svc/WrapperFactory.html[`WrapperFactory`].
+Commands are also used under the covers to allow actions invocations to be made asynchronously using the link:https://isis.apache.org/refguide/2.0.0-M3/applib-svc/WrapperFactory.html[`WrapperFactory`].
+This can be useful for long-running actions.
 
 [NOTE]
 ====
-The list of persisted ``Command``s can be viewed in a collection at the bottom of the page.
+The list of persisted ``Command``s can be viewed in a collection on the left bottom of this page.
 ``Command``s are persisted after the page rendering phase, so to view a just-persisted command, refresh the page.
 
-(If running in prototype mode), the list of persisted ``Command``s can also be truncated from the activity menu.
+If running in prototype mode, the list of persisted ``Command``s can also be truncated from the activity menu.
 ====
 
 == Annotated
@@ -109,7 +110,7 @@ include::ActionCommandJdo_mixinUpdatePropertyMetaAnnotationOverridden.java[tags=
 == CommandServiceListener
 
 The demo includes the link:https://isis.apache.org/extensions/2.0.0-M3/command-log/about.html[Command Log] extension, so every command is persisted.
-These can be viewed in the collection at the bottom of the page.
+These can be viewed in the collection at the left bottom of the page.
 ``Command``s are persisted after the page rendering phase, so to view a just-persisted command, refresh the page.
 
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml
index 9207772..70a6544 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml
@@ -21,6 +21,7 @@
 			<cpt:fieldSet name="Meta-annotated" id="meta-annotated"/>
 			<cpt:fieldSet name="Meta-annotated Overridden" id="meta-annotated-overridden"/>
 			<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+			<cpt:collection id="commands"/>
 		</bs3:col>
 		<bs3:col span="6">
 			<cpt:fieldSet name="Description" id="description" >
@@ -36,11 +37,6 @@
 		</bs3:col>
 	</bs3:row>
 	<bs3:row>
-		<bs3:col span="12">
-			<cpt:collection id="commands"/>
-		</bs3:col>
-	</bs3:row>
-	<bs3:row>
 		<bs3:col span="12" unreferencedCollections="true"/>
 	</bs3:row>
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Collection/CollectionMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Collection/CollectionMenu.java
index 7ff4865..5b37063 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Collection/CollectionMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Collection/CollectionMenu.java
@@ -25,12 +25,14 @@ import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.value.Blob;
 
+import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
 import demoapp.dom.types.Samples;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.CollectionMenu")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class CollectionMenu {
 
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/DomainObject/DomainObjectMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/DomainObject/DomainObjectMenu.java
index 48b91b3..9640227 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/DomainObject/DomainObjectMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/DomainObject/DomainObjectMenu.java
@@ -18,18 +18,22 @@
  */
 package demoapp.dom.annotDomain.DomainObject;
 
+import javax.inject.Inject;
+
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
+import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
 import demoapp.dom.annotDomain.DomainObject.publishing.DomainObjectPublishingVm;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.DomainObjectMenu")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class DomainObjectMenu {
 
     @Action(semantics = SemanticsOf.SAFE)
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/PropertyMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/PropertyMenu.java
index b97d5c3..32d20f1 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/PropertyMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/PropertyMenu.java
@@ -30,9 +30,12 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.applib.value.Clob;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
+import demoapp.dom.annotDomain.Property.command.PropertyCommandJdo;
+import demoapp.dom.annotDomain.Property.command.PropertyCommandJdoEntities;
 import demoapp.dom.annotDomain.Property.domainEvent.PropertyDomainEventVm;
 import demoapp.dom.annotDomain.Property.editing.PropertyEditingVm;
 import demoapp.dom.annotDomain.Property.fileAccept.PropertyFileAcceptVm;
@@ -48,8 +51,21 @@ import demoapp.dom.types.Samples;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.PropertyMenu")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class PropertyMenu {
 
+    final PropertyCommandJdoEntities propertyCommandJdoEntities;
+    final PropertyPublishingJdoEntities propertyPublishingJdoEntities;
+    final Samples<Blob> blobSamples;
+    final Samples<Clob> clobSamples;
+
+    @Action(semantics = SemanticsOf.SAFE)
+    @ActionLayout(cssClassFa="fa-terminal", describedAs = "Action invocation intentions as XML")
+    public PropertyCommandJdo command(){
+        return propertyCommandJdoEntities.first();
+    }
+
+
     @Action(semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa="fa-asterisk", describedAs = "Decouples interaction of properties")
     public PropertyDomainEventVm domainEvent(){
@@ -158,11 +174,5 @@ public class PropertyMenu {
                 .ifPresent(clobConsumer);
     }
 
-    @Inject
-    Samples<Blob> blobSamples;
-    @Inject
-    Samples<Clob> clobSamples;
-    @Inject
-    PropertyPublishingJdoEntities propertyPublishingJdoEntities;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandDisabledMetaAnnotation.java
similarity index 50%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java
copy to examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandDisabledMetaAnnotation.java
index fd271ba..3ef1f74 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandDisabledMetaAnnotation.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandDisabledMetaAnnotation.java
@@ -1,4 +1,4 @@
-package demoapp.dom.annotDomain.Action.command;
+package demoapp.dom.annotDomain.Property.command;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
@@ -7,15 +7,17 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.CommandReification;
+import org.apache.isis.applib.annotation.Property;
 
 //tag::class[]
-@Action()                                       // <.>
+@Property(command = CommandReification.DISABLED)    // <.>
 @Inherited
 @Target({
-        ElementType.TYPE, ElementType.METHOD    // <.>
+        ElementType.FIELD, ElementType.METHOD       // <.>
 })
 @Retention(RetentionPolicy.RUNTIME)
-public @interface ActionCommandDisabledMetaAnnotation {
+public @interface PropertyCommandDisabledMetaAnnotation {
 
 }
 //end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandEnabledMetaAnnotation.java
similarity index 54%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java
copy to examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandEnabledMetaAnnotation.java
index 62e0d52..392b2fb 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandEnabledMetaAnnotation.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandEnabledMetaAnnotation.java
@@ -1,4 +1,4 @@
-package demoapp.dom.annotDomain.Action.command;
+package demoapp.dom.annotDomain.Property.command;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
@@ -7,16 +7,18 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.CommandReification;
+import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.Publishing;
 
 //tag::class[]
-@Action(publishing = Publishing.ENABLED)        // <.>
+@Property(command = CommandReification.ENABLED) // <.>
 @Inherited
 @Target({
-        ElementType.TYPE, ElementType.METHOD    // <.>
+        ElementType.FIELD, ElementType.METHOD   // <.>
 })
 @Retention(RetentionPolicy.RUNTIME)
-public @interface ActionCommandEnabledMetaAnnotation {
+public @interface PropertyCommandEnabledMetaAnnotation {
 
 }
 //end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo-description.adoc
similarity index 68%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc
copy to examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo-description.adoc
index e3f3ad6..9db4777 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo-description.adoc
@@ -1,57 +1,37 @@
-The `command` semantic is used to allow or suppress the reification of an action invocation or property edit into a `Command`.
+The `command` semantic is used to allow or suppress the reification of an property edit into a `Command`.
 
 When allowed (the default), then the `Command` is sent to registered implementation(s) of https://isis.apache.org/refguide/2.0.0-M3/applib-svc/CommandServiceListener.html#section-top[`CommandServiceListener`] SPI, _after_ the interaction has completed.
 One use case is to replicate and replay commands to a secondary system, for example for regression testing.
-For more on this, see "Command Replay" section below.
+For more on this, see the "Command Replay" section below.
 
-Commands are also used under the covers to allow actions/edits to be called asynchronously using the link:https://isis.apache.org/refguide/2.0.0-M3/applib-svc/WrapperFactory.html[`WrapperFactory`].
+Commands are also used under the covers to allow property edits to be made asynchronously using the link:https://isis.apache.org/refguide/2.0.0-M3/applib-svc/WrapperFactory.html[`WrapperFactory`].
 
 [NOTE]
 ====
-The list of persisted ``Command``s can be viewed in a collection at the bottom of the page.
+The list of persisted ``Command``s can be viewed in a collection at the left bottom of the page.
 ``Command``s are persisted after the page rendering phase, so to view a just-persisted command, refresh the page.
 
-(If running in prototype mode), the list of persisted ``Command``s can also be truncated from the activity menu.
+If running in prototype mode, the list of persisted ``Command``s can also be truncated from the activity menu.
 ====
 
 == Annotated
 
-The `command` semantic can be specified explicitly using an annotation through `@Action#command()`:
+The `command` semantic can be specified explicitly using an annotation through `@Property#command()`:
 
-* it can be applied to an action:
-+
 [source,java,indent=0]
 ----
-include::ActionCommandJdo.java[tags=annotation]
+include::PropertyCommandJdo.java[tags=annotation]
 ----
 <.> explicitly specifies that invoking the action should be reified .
 
-* or to a mixin:
-+
-[source,java,indent=0]
-----
-include::ActionCommandJdo_mixinUpdateProperty.java[tags=class]
-----
-<.> explicitly specifies that invoking the mixin action should be reified.
-
 The command reification can also be disabled:
 
-* for an action:
-+
 [source,java,indent=0]
 ----
-include::ActionCommandJdo.java[tags=annotation-2]
+include::PropertyCommandJdo.java[tags=annotation-2]
 ----
 <.> explicitly specifies that invoking the action should not be reified.
 
-* or to a mixin:
-+
-[source,java,indent=0]
-----
-include::ActionCommandJdo_mixinUpdatePropertyCommandDisabled.java[tags=class]
-----
-<.> explicitly specifies that invoking the mixin action should not be reified.
-
 
 == Meta-annotated
 
@@ -61,24 +41,16 @@ The `command` semantic can also be specified using a custom meta-annotation:
 +
 [source,java,indent=0]
 ----
-include::ActionCommandEnabledMetaAnnotation.java[tags=class]
+include::PropertyCommandEnabledMetaAnnotation.java[tags=class]
 ----
-<.> annotated for an action
-<.> annotation can be applied to an action method or to a mixin
+<.> annotated for a property
+<.> annotation can be applied to a property field or getter method
 
-* and can be applied to an action:
+* and can be applied to a property:
 +
 [source,java,indent=0]
 ----
-include::ActionCommandJdo.java[tags=meta-annotation]
-----
-<.> semantic is inherited from the meta-annotation
-
-* or to a mixin:
-+
-[source,java,indent=0]
-----
-include::ActionCommandJdo_mixinUpdatePropertyMetaAnnotation.java[tags=class]
+include::PropertyCommandJdo.java[tags=meta-annotation]
 ----
 <.> semantic is inherited from the meta-annotation
 
@@ -87,29 +59,19 @@ include::ActionCommandJdo_mixinUpdatePropertyMetaAnnotation.java[tags=class]
 
 The meta-annotation can itself be overridden:
 
-* for an action:
-+
 [source,java,indent=0]
 ----
-include::ActionCommandJdo.java[tags=meta-annotation-overridden]
+include::PropertyCommandJdo.java[tags=meta-annotation-overridden]
 ----
 <.> semantic from meta-annotation ...
-<.> \... is overridden by the `@Action` annotation
+<.> \... is overridden by the `@Property` annotation
 
-* or on a mixin:
-+
-[source,java,indent=0]
-----
-include::ActionCommandJdo_mixinUpdatePropertyMetaAnnotationOverridden.java[tags=class]
-----
-<.> semantic from meta-annotation ...
-<.> \... is overridden by the `@Action` annotation
 
 
 == CommandServiceListener
 
 The demo includes the link:https://isis.apache.org/extensions/2.0.0-M3/command-log/about.html[Command Log] extension, so every command is persisted.
-These can be viewed in the collection at the bottom of the page.
+These can be viewed in the collection at the bottom of the left page.
 ``Command``s are persisted after the page rendering phase, so to view a just-persisted command, refresh the page.
 
 
@@ -124,7 +86,7 @@ This can be configured globally:
 isis:
   applib:
     annotation:
-      action:
+      property:
         command: none   # or 'all', or 'ignore_safe'
 ----
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.java
new file mode 100644
index 0000000..466dab3
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package demoapp.dom.annotDomain.Property.command;
+
+import javax.jdo.annotations.DatastoreIdentity;
+import javax.jdo.annotations.IdGeneratorStrategy;
+import javax.jdo.annotations.IdentityType;
+import javax.jdo.annotations.PersistenceCapable;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.CommandReification;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.SemanticsOf;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import demoapp.dom.annotDomain._commands.ExposePersistedCommands;
+
+//tag::class[]
+@PersistenceCapable(identityType = IdentityType.DATASTORE, schema = "demo")
+@DatastoreIdentity(strategy = IdGeneratorStrategy.IDENTITY, column = "id")
+@DomainObject(
+        nature=Nature.JDO_ENTITY
+        , objectType = "demo.PropertyCommandJdo"
+        , editing = Editing.ENABLED
+)
+public class PropertyCommandJdo
+        implements HasAsciiDocDescription, ExposePersistedCommands {
+    // ...
+//end::class[]
+
+    public PropertyCommandJdo(String initialValue) {
+        this.property = initialValue;
+        this.propertyCommandDisabled = initialValue;
+        this.propertyMetaAnnotated = initialValue;
+        this.propertyMetaAnnotatedOverridden = initialValue;
+    }
+
+    public String title() {
+        return "Property#command";
+    }
+
+//tag::annotation[]
+    @Property(
+        command = CommandReification.ENABLED             // <.>
+    )
+    @PropertyLayout(
+        describedAs = "@Property(command = ENABLED)"
+    )
+    @MemberOrder(name = "annotation", sequence = "1")
+    @Getter @Setter
+    private String property;
+//end::annotation[]
+
+//tag::annotation-2[]
+    @Property(
+        command = CommandReification.DISABLED           // <.>
+    )
+    @PropertyLayout(
+        describedAs = "@Property(command = DISABLED)"
+    )
+    @MemberOrder(name = "annotation", sequence = "2")
+    @Getter @Setter
+    private String propertyCommandDisabled;
+//end::annotation-2[]
+
+//tag::meta-annotation[]
+    @PropertyCommandEnabledMetaAnnotation               // <.>
+    @PropertyLayout(
+            describedAs = "@PropertyCommandEnabledMetaAnnotation"
+    )
+    @MemberOrder(name = "meta-annotated", sequence = "1")
+    @Getter @Setter
+    private String propertyMetaAnnotated;
+//end::meta-annotation[]
+
+//tag::meta-annotation-overridden[]
+    @PropertyCommandDisabledMetaAnnotation              // <.>
+    @Property(command = CommandReification.ENABLED)     // <.>
+    @PropertyLayout(
+        describedAs =
+            "@PropertyCommandDisabledMetaAnnotation " +
+            "@Property(command = ENABLED)"
+    )
+    @MemberOrder(name = "meta-annotated-overridden", sequence = "1")
+    @Getter @Setter
+    private String propertyMetaAnnotatedOverridden;
+//end::meta-annotation-overridden[]
+
+//tag::class[]
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.layout.xml
similarity index 96%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml
copy to examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.layout.xml
index 9207772..70a6544 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdo.layout.xml
@@ -21,6 +21,7 @@
 			<cpt:fieldSet name="Meta-annotated" id="meta-annotated"/>
 			<cpt:fieldSet name="Meta-annotated Overridden" id="meta-annotated-overridden"/>
 			<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+			<cpt:collection id="commands"/>
 		</bs3:col>
 		<bs3:col span="6">
 			<cpt:fieldSet name="Description" id="description" >
@@ -36,11 +37,6 @@
 		</bs3:col>
 	</bs3:row>
 	<bs3:row>
-		<bs3:col span="12">
-			<cpt:collection id="commands"/>
-		</bs3:col>
-	</bs3:row>
-	<bs3:row>
 		<bs3:col span="12" unreferencedCollections="true"/>
 	</bs3:row>
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoEntities.java
new file mode 100644
index 0000000..edf1d9a
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoEntities.java
@@ -0,0 +1,34 @@
+package demoapp.dom.annotDomain.Property.command;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.services.repository.RepositoryService;
+
+import lombok.RequiredArgsConstructor;
+
+@Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
+public class PropertyCommandJdoEntities {
+
+    final RepositoryService repositoryService;
+
+    public Optional<PropertyCommandJdo> find(final String value) {
+        return repositoryService.firstMatch(PropertyCommandJdo.class, x -> Objects.equals(x.getProperty(), value));
+    }
+
+    public List<PropertyCommandJdo> all() {
+        return repositoryService.allInstances(PropertyCommandJdo.class);
+    }
+
+    public PropertyCommandJdo first() {
+        return all().stream().findFirst().get();
+    }
+
+
+}
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoSeedService.java
similarity index 80%
copy from examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java
copy to examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoSeedService.java
index 3389e0e..a521785 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/PropertyCommandJdoSeedService.java
@@ -1,4 +1,4 @@
-package demoapp.dom.services.wrapperFactory;
+package demoapp.dom.annotDomain.Property.command;
 
 import javax.inject.Inject;
 
@@ -11,9 +11,9 @@ import demoapp.dom._infra.seed.SeedServiceAbstract;
 import demoapp.dom.types.Samples;
 
 @Service
-public class WrapperFactoryJdoSeedService extends SeedServiceAbstract {
+public class PropertyCommandJdoSeedService extends SeedServiceAbstract {
 
-    public WrapperFactoryJdoSeedService() {
+    public PropertyCommandJdoSeedService() {
         super(PropertyPublishingJdoEntityFixture::new);
     }
 
@@ -22,7 +22,7 @@ public class WrapperFactoryJdoSeedService extends SeedServiceAbstract {
         @Override
         protected void execute(ExecutionContext executionContext) {
             samples.stream()
-                    .map(WrapperFactoryJdo::new)
+                    .map(PropertyCommandJdo::new)
                     .forEach(domainObject -> {
                         repositoryService.persist(domainObject);
                         executionContext.addResult(this, domainObject);
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/domainEvent/subscribers/PropertyDomainEventControlService.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/domainEvent/subscribers/PropertyDomainEventControlService.java
index cbaa14c..977d29d 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/domainEvent/subscribers/PropertyDomainEventControlService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/domainEvent/subscribers/PropertyDomainEventControlService.java
@@ -8,12 +8,17 @@ import org.springframework.context.event.EventListener;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 
+import lombok.RequiredArgsConstructor;
+
 import demoapp.dom.annotDomain.Property.domainEvent.PropertyDomainEventVm;
 
 // tag::class[]
 @DomainService(objectType = "demo.PropertyDomainEventControlService")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 class PropertyDomainEventControlService {
 
+    final ServiceRegistry serviceRegistry;
+
     PropertyDomainEventControlStrategy controlStrategy = PropertyDomainEventControlStrategy.DO_NOTHING;   // <.>
 
     @EventListener(PropertyDomainEventVm.TextDomainEvent.class)     // <.>
@@ -21,7 +26,5 @@ class PropertyDomainEventControlService {
         controlStrategy.on(ev, serviceRegistry);
     }
 
-    @Inject
-    ServiceRegistry serviceRegistry;
 }
 // end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/publishing/PropertyPublishingJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/publishing/PropertyPublishingJdoSeedService.java
index c45cd79..18679ee 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/publishing/PropertyPublishingJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/publishing/PropertyPublishingJdoSeedService.java
@@ -7,6 +7,8 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
 
+import lombok.RequiredArgsConstructor;
+
 import demoapp.dom._infra.seed.SeedServiceAbstract;
 import demoapp.dom.types.Samples;
 
@@ -30,10 +32,7 @@ public class PropertyPublishingJdoSeedService extends SeedServiceAbstract {
 
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<String> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<String> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/PropertyLayoutMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/PropertyLayoutMenu.java
index da4204f..6587c80 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/PropertyLayoutMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/PropertyLayoutMenu.java
@@ -28,6 +28,7 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.value.Blob;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -46,8 +47,12 @@ import demoapp.dom.types.Samples;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.PropertyLayoutMenu")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class PropertyLayoutMenu {
 
+    final ClockService clockService;
+    final Samples<Blob> samples;
+
     @Action(semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa="fa-file-code", describedAs = "HTML styling")
     public PropertyLayoutCssClassVm cssClass(){
@@ -148,10 +153,5 @@ public class PropertyLayoutMenu {
         return vm;
     }
 
-    @Inject
-    ClockService clockService;
-
-    @Inject
-    Samples<Blob> samples;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/navigable/FileTreeNodeService.java b/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/navigable/FileTreeNodeService.java
index f79a317..68a6018 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/navigable/FileTreeNodeService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotLayout/PropertyLayout/navigable/FileTreeNodeService.java
@@ -30,13 +30,17 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.graph.tree.TreeNode;
 import org.apache.isis.applib.graph.tree.TreePath;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 //tag::sessionTree[]
 @Service
 @Named("demo.FileTreeNodeService")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class FileTreeNodeService {
 
+    final Provider<HttpSession> httpSessionProvider;
+
     public TreeNode<FileNodeVm> sessionTree() {
         TreeNode<FileNodeVm> tree = (TreeNode<FileNodeVm>) httpSessionProvider.get().getAttribute(TreeNode.class.getName());
         if(tree == null) {
@@ -60,10 +64,6 @@ public class FileTreeNodeService {
 
 
 //tag::sessionTree[]
-
     // ...
-
-    @Inject
-    private Provider<HttpSession> httpSessionProvider;
 }
 //end::sessionTree[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/error/ErrorMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/error/ErrorMenu.java
index 07d6b71..48204ed 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/error/ErrorMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/error/ErrorMenu.java
@@ -27,13 +27,15 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.ErrorMenu")
 @DomainObjectLayout(named="Error Handling")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class ErrorMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(cssClassFa="fa-bolt")
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/events/DemoEventSubscriber.java b/examples/demo/domain/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
index 7b84a69..bbba2e07 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
@@ -32,6 +32,7 @@ import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.control.AsyncControl;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -43,10 +44,11 @@ import static demoapp.dom._infra.utils.LogUtils.emphasize;
 @Named("demoapp.eventSubscriber")
 @Qualifier("demo")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class DemoEventSubscriber {
 
-    @Inject private WrapperFactory wrapper;
-    @Inject private FactoryService factoryService;
+    final WrapperFactory wrapper;
+    final FactoryService factoryService;
     
     @EventListener(UiButtonEvent.class) // <-- listen on the event, triggered by button in the UI 
     public void on(UiButtonEvent event) {
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/events/EventLogRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/events/EventLogRepository.java
index 8041580..dd50986 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/events/EventLogRepository.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/events/EventLogRepository.java
@@ -27,18 +27,21 @@ import org.springframework.stereotype.Repository;
 
 import org.apache.isis.applib.services.repository.RepositoryService;
 
+import lombok.RequiredArgsConstructor;
+
 @Repository
 @Named("demoapp.eventLogRepository")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class EventLogRepository {
 
-    @Inject private RepositoryService repository;
+    final RepositoryService repositoryService;
 
     public List<EventLogEntry> listAll(){
-        return repository.allInstances(EventLogEntry.class);
+        return repositoryService.allInstances(EventLogEntry.class);
     }
 
     public void add(EventLogEntry entry) {
-        repository.persist(entry);
+        repositoryService.persist(entry);
     }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/events/EventsDemoMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/events/EventsDemoMenu.java
index 1729fe7..08ce9d6 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/events/EventsDemoMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/events/EventsDemoMenu.java
@@ -27,13 +27,15 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.EventsDemoMenu")
 @DomainObjectLayout(named="Events Demo")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class EventsDemoMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(cssClassFa="fa-bolt")
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/TenantedJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/TenantedJdoEntities.java
index ce07ac8..be21d86 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/TenantedJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/TenantedJdoEntities.java
@@ -8,14 +8,17 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.services.repository.RepositoryService;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class TenantedJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public List<TenantedJdo> all() {
         return repositoryService.allInstances(TenantedJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/seed/TenantedJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/seed/TenantedJdoSeedService.java
index 5819ebd..2673e6d 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/seed/TenantedJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/extensions/secman/apptenancy/entities/seed/TenantedJdoSeedService.java
@@ -30,12 +30,8 @@ public class TenantedJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        NameSamples secManNameSamples;
+        @Inject RepositoryService repositoryService;
+        @Inject NameSamples secManNameSamples;
     }
 
-
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/jee/JeeMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/jee/JeeMenu.java
index 0a5afe9..96578b5 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/jee/JeeMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/jee/JeeMenu.java
@@ -26,12 +26,14 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.JeeMenu")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class JeeMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(cssClassFa="fa-bolt")
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
index 2a04eaa..b6924a7 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
@@ -122,6 +122,7 @@ as a replacement for
             </mb3:section>
             <mb3:section>
                 <mb3:named>@Property</mb3:named>
+                <mb3:serviceAction objectType="demo.PropertyMenu" id="command"/>
                 <mb3:serviceAction objectType="demo.PropertyMenu" id="domainEvent"/>
                 <mb3:serviceAction objectType="demo.PropertyMenu" id="editing"/>
                 <mb3:serviceAction objectType="demo.PropertyMenu" id="fileAccept"/>
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/mixins/MixinMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/mixins/MixinMenu.java
index e80b99d..18c14b8 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/mixins/MixinMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/mixins/MixinMenu.java
@@ -28,12 +28,14 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.MixinMenu")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class MixinMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/mixins/legacy/MixinLegacyMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/mixins/legacy/MixinLegacyMenu.java
index 10fb747..f895555 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/mixins/legacy/MixinLegacyMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/mixins/legacy/MixinLegacyMenu.java
@@ -28,14 +28,16 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 import demoapp.dom.mixins.DemoItem;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.MixinLegacyMenu")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class MixinLegacyMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java
index 3389e0e..4de0efe 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/services/wrapperFactory/WrapperFactoryJdoSeedService.java
@@ -30,10 +30,7 @@ public class WrapperFactoryJdoSeedService extends SeedServiceAbstract {
 
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<String> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<String> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/tabs/TabMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/tabs/TabMenu.java
index 2abab10..f3035bc 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/tabs/TabMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/tabs/TabMenu.java
@@ -26,17 +26,20 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.TabMenu")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class TabMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(
             cssClassFa="fa-bolt",
-            describedAs="Opens the Tabs-Demo page.")
+            describedAs="Opens the Tabs-Demo page."
+    )
     public TabDemo tabDemo(){
         return factoryService.viewModel(TabDemo.class);
     }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/tooltip/TooltipMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/tooltip/TooltipMenu.java
index 9f54912..425ba99 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/tooltip/TooltipMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/tooltip/TooltipMenu.java
@@ -28,14 +28,16 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.factory.FactoryService;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 import demoapp.dom.actions.assoc.DemoItem;
 
 @DomainService(nature=NatureOfService.VIEW, objectType = "demo.TooltipMenu")
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class TooltipMenu {
 
-    @Inject private FactoryService factoryService;
+    final FactoryService factoryService;
 
     @Action
     @ActionLayout(
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoEntities.java
index 0afdd80..d475904 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoEntities.java
@@ -10,9 +10,14 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Blob;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class IsisBlobJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public Optional<IsisBlobJdo> find(final Blob readOnlyProperty) {
         return repositoryService.firstMatch(IsisBlobJdo.class, x -> x.getReadOnlyProperty() == readOnlyProperty);
     }
@@ -21,7 +26,5 @@ public class IsisBlobJdoEntities {
         return repositoryService.allInstances(IsisBlobJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoSeedService.java
index 1726c47..d9696b7 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/blobs/jdo/IsisBlobJdoSeedService.java
@@ -31,10 +31,7 @@ public class IsisBlobJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<Blob> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<Blob> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoEntities.java
index d970bda..35c1056 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoEntities.java
@@ -10,9 +10,14 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Clob;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class IsisClobJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public Optional<IsisClobJdo> find(final Clob readOnlyProperty) {
         return repositoryService.firstMatch(IsisClobJdo.class, x -> x.getReadOnlyProperty() == readOnlyProperty);
     }
@@ -21,7 +26,5 @@ public class IsisClobJdoEntities {
         return repositoryService.allInstances(IsisClobJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoSeedService.java
index 158bacc..f056b81 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/clobs/jdo/IsisClobJdoSeedService.java
@@ -30,10 +30,7 @@ public class IsisClobJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<Clob> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<Clob> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoEntities.java
index 143a771..542efc9 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoEntities.java
@@ -10,9 +10,14 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Image;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class IsisImageJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public Optional<IsisImageJdo> find(final Image readOnlyProperty) {
         return repositoryService.firstMatch(IsisImageJdo.class, x -> x.getReadOnlyProperty() == readOnlyProperty);
     }
@@ -21,7 +26,4 @@ public class IsisImageJdoEntities {
         return repositoryService.allInstances(IsisImageJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
-
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoSeedService.java
index 4c4833b..1c8969d 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/images/jdo/IsisImageJdoSeedService.java
@@ -30,10 +30,7 @@ public class IsisImageJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<Image> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<Image> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoEntities.java
index d7dbe13..ac19925 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoEntities.java
@@ -10,9 +10,14 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.LocalResourcePath;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class IsisLocalResourcePathJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public Optional<IsisLocalResourcePathJdo> find(final LocalResourcePath readOnlyProperty) {
         return repositoryService.firstMatch(IsisLocalResourcePathJdo.class, x -> x.getReadOnlyProperty() == readOnlyProperty);
     }
@@ -21,7 +26,5 @@ public class IsisLocalResourcePathJdoEntities {
         return repositoryService.allInstances(IsisLocalResourcePathJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoSeedService.java
index 131e0ac..5472819 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/localresourcepaths/jdo/IsisLocalResourcePathJdoSeedService.java
@@ -30,10 +30,7 @@ public class IsisLocalResourcePathJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
-
-        @Inject
-        Samples<LocalResourcePath> samples;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<LocalResourcePath> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoEntities.java
index b79076d..b5552fc 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoEntities.java
@@ -10,9 +10,14 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Markup;
 
+import lombok.RequiredArgsConstructor;
+
 @Service
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class IsisMarkupJdoEntities {
 
+    final RepositoryService repositoryService;
+
     public Optional<IsisMarkupJdo> find(final Markup readOnlyProperty) {
         return repositoryService.firstMatch(IsisMarkupJdo.class, x -> x.getReadOnlyProperty() == readOnlyProperty);
     }
@@ -21,7 +26,5 @@ public class IsisMarkupJdoEntities {
         return repositoryService.allInstances(IsisMarkupJdo.class);
     }
 
-    @Inject
-    RepositoryService repositoryService;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoSeedService.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoSeedService.java
index d1e971a..d56bceb 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoSeedService.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdoSeedService.java
@@ -30,10 +30,8 @@ public class IsisMarkupJdoSeedService extends SeedServiceAbstract {
                     });
         }
 
-        @Inject
-        RepositoryService repositoryService;
+        @Inject RepositoryService repositoryService;
+        @Inject Samples<Markup> samples;
 
-        @Inject
-        Samples<Markup> samples;
     }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep b/examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/chg/.gitkeep
similarity index 100%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep
copy to examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/chg/.gitkeep
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep b/examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/cmd/.gitkeep
similarity index 100%
copy from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep
copy to examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/cmd/.gitkeep
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep b/examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/ixn/.gitkeep
similarity index 100%
rename from examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Property/command/.gitkeep
rename to examples/demo/domain/src/main/java/demoapp/dom/types/isisschema/ixn/.gitkeep
diff --git a/examples/demo/domain/src/main/resources/application.yml b/examples/demo/domain/src/main/resources/application.yml
index 2134d0c..6f8678b 100644
--- a/examples/demo/domain/src/main/resources/application.yml
+++ b/examples/demo/domain/src/main/resources/application.yml
@@ -19,9 +19,11 @@
 #
 isis:
 
+
   applib:
     annotation:
       action:
+        command: ignore_safe
         explicit: true
         publishing: none
       action-layout:
@@ -41,6 +43,7 @@ isis:
         editing: false
         publishing: none
       property:
+        command: all
         publishing: none
       property-layout:
         label-position: LEFT
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/linebreaker/LineBreaker.java b/examples/demo/web/src/main/java/demoapp/web/linebreaker/LineBreaker.java
similarity index 82%
rename from examples/demo/domain/src/main/java/demoapp/dom/linebreaker/LineBreaker.java
rename to examples/demo/web/src/main/java/demoapp/web/linebreaker/LineBreaker.java
index ea02f5f..5ca588c 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/linebreaker/LineBreaker.java
+++ b/examples/demo/web/src/main/java/demoapp/web/linebreaker/LineBreaker.java
@@ -1,4 +1,4 @@
-package demoapp.dom.linebreaker;
+package demoapp.web.linebreaker;
 
 import javax.inject.Inject;
 
@@ -8,6 +8,7 @@ import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.core.runtime.iactn.IsisInteractionTracker;
 
+import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
 /**
@@ -17,8 +18,11 @@ import lombok.extern.log4j.Log4j2;
  */
 @DomainService(nature = NatureOfService.REST, objectType = "demo.LineBreaker")
 @Log4j2
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
 public class LineBreaker {
-    
+
+    final IsisInteractionTracker isisInteractionTracker;
+
     @Action(semantics = SemanticsOf.SAFE)
     public void shutdown() {
         log.info("about to shutdown the JVM");
@@ -30,7 +34,5 @@ public class LineBreaker {
         });
     }
 
-    @Inject
-    IsisInteractionTracker isisInteractionTracker;
-    
+
 }
diff --git a/extensions/core/command-replay/secondary/pom.xml b/extensions/core/command-replay/secondary/pom.xml
index 5bafd00..a321a5f 100644
--- a/extensions/core/command-replay/secondary/pom.xml
+++ b/extensions/core/command-replay/secondary/pom.xml
@@ -65,10 +65,12 @@
             <artifactId>isis-mappings-jaxrsclient-impl</artifactId>
         </dependency>
 
+<!--
         <dependency>
             <groupId>org.apache.isis.extensions</groupId>
             <artifactId>isis-extensions-command-log-jdo</artifactId>
         </dependency>
+-->
 
         <dependency>
             <groupId>org.apache.isis.extensions</groupId>
diff --git a/viewers/wicket/adoc/modules/ROOT/partials/security/user-registration.adoc b/viewers/wicket/adoc/modules/ROOT/partials/security/user-registration.adoc
index 6f7443f..a576bdd 100644
--- a/viewers/wicket/adoc/modules/ROOT/partials/security/user-registration.adoc
+++ b/viewers/wicket/adoc/modules/ROOT/partials/security/user-registration.adoc
@@ -7,7 +7,7 @@
 
 As well as providing a sign-in screen, the Wicket viewer also provides the ability for users to self-register.
 By and large this operates outside of Apache Isis' security mechanisms; indeed the various pages (sign-up, sign-up verification, password reset) are all rendered _without_ there being any current user session.
-These pages all "reach inside" Apache Isis framework using a mechanism similar to xref:userguide:btb:headless-access.adoc[Headless access] in order to actually do their stuff.
+These pages all "reach inside" Apache Isis framework in order to actually do their stuff.
 
 [TIP]
 ====