You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/09/06 11:16:38 UTC

[isis] branch ISIS-1976-rethink-object-adapters updated (67fd1ec -> 2d01709)

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

ahuber pushed a change to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from 67fd1ec  ISIS-1976: further simplify
     new e0594d0  ISIS-1976: lazy initialize OAs for services
     new 2d01709  ISIS-1976: cleaning up

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../metamodel/adapter/ObjectAdapterProvider.java   |  18 +--
 .../core/metamodel/services/ServicesInjector.java  |   8 ++
 .../system/persistence/PersistenceSession4.java    |  65 +---------
 .../system/persistence/PersistenceSession5.java    |  65 +---------
 .../persistence/PersistenceSession5_Decouple.java  |  16 ++-
 .../system/persistence/PersistenceSession.java     |  14 +-
 .../adaptermanager/ObjectAdapterContext.java       |  51 +++++---
 .../ObjectAdapterContext_NewIdentifier.java        | 129 +++++++++++++++++++
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 142 +++++++++++----------
 .../ObjectAdapterContext_ServiceLookup.java        | 109 ++++++++++++++++
 10 files changed, 393 insertions(+), 224 deletions(-)
 create mode 100644 core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java
 create mode 100644 core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java


[isis] 02/02: ISIS-1976: cleaning up

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2d0170953be32f1291801f7e84a2cacf03e770e5
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 13:16:18 2018 +0200

    ISIS-1976: cleaning up
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../adaptermanager/ObjectAdapterContext.java       | 18 +-----------
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 32 +++++++++++-----------
 .../ObjectAdapterContext_ServiceLookup.java        |  2 +-
 3 files changed, 18 insertions(+), 34 deletions(-)

diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index b204e36..44fc112 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -135,7 +135,6 @@ public class ObjectAdapterContext {
     
     private final Cache cache = new Cache();
     
-    @SuppressWarnings("unused")
     private final PersistenceSession persistenceSession; 
     private final ServicesInjector servicesInjector;
     private final SpecificationLoader specificationLoader;
@@ -171,7 +170,7 @@ public class ObjectAdapterContext {
 
     // -- DEBUG
     
-    private void printContextInfo(String msg) {
+    void printContextInfo(String msg) {
         String id = Integer.toHexString(this.hashCode());
         String session = ""+persistenceSession;
         System.out.println("!!!!!!!!!!!!!!!!!!!!!!! "+String.format("%s id=%s session='%s'", 
@@ -360,21 +359,6 @@ public class ObjectAdapterContext {
     
     // ------------------------------------------------------------------------------------------------
     
-//    /**
-//     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
-//     * and have the same OIDs as in any previous sessions.
-//     * 
-//     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
-//     */
-//    @Deprecated
-//    private void initServices() {
-//        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
-//        for (final Object service : registeredServices) {
-//            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
-//            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
-//        }
-//    }
-    
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
             final ObjectSpecification objectSpecification = 
                     specificationLoader.loadSpecification(viewModelPojo.getClass());
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index a8f33ce..b231b0c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -145,6 +145,15 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         return adapter;
     }
     
+    @Override
+    public List<ObjectAdapter> getServices() {
+        return serviceAdapters.get();
+    }
+    
+    // -- HELPER
+    
+    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
+    
     private List<ObjectAdapter> initServiceAdapters() {
         return servicesInjector.streamRegisteredServiceInstances()
         .map(this::adapterFor)
@@ -154,15 +163,6 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         .collect(Collectors.toList());
     }
     
-    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
-    
-    @Override
-    public List<ObjectAdapter> getServices() {
-        return serviceAdapters.get();
-    }
-    
-    // -- HELPER
-    
 //    private Oid persistentOrValueOid(Object pojo) {
 //        
 //        Oid oid;
@@ -197,13 +197,13 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
 //        return null;
 //    }
     
-    protected Oid persistentOid(final Object pojo) {
-        if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
-            return null;
-        }
-        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
-        return oid;
-    }
+//    private Oid persistentOid(final Object pojo) {
+//        if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
+//            return null;
+//        }
+//        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
+//        return oid;
+//    }
     
     private ObjectAdapter existingOrValueAdapter(Object pojo) {
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
index 31d3b39..ae92baa 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -91,7 +91,7 @@ class ObjectAdapterContext_ServiceLookup {
     
     private ServicesByIdResource initLookupResource() {
         
-        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! INIT SERVICE ID LOOKUP RESOURCE");
+        objectAdapterContext.printContextInfo("INIT SERVICE ID LOOKUP RESOURCE");
         
         final ServicesByIdResource lookupResource = new ServicesByIdResource();
         


[isis] 01/02: ISIS-1976: lazy initialize OAs for services

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit e0594d07c15068b3c4c9035ceaec78f40a5ab15a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 13:02:52 2018 +0200

    ISIS-1976: lazy initialize OAs for services
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../metamodel/adapter/ObjectAdapterProvider.java   |  18 +--
 .../core/metamodel/services/ServicesInjector.java  |   8 ++
 .../system/persistence/PersistenceSession4.java    |  65 +---------
 .../system/persistence/PersistenceSession5.java    |  65 +---------
 .../persistence/PersistenceSession5_Decouple.java  |  16 ++-
 .../system/persistence/PersistenceSession.java     |  14 ++-
 .../adaptermanager/ObjectAdapterContext.java       |  63 +++++++---
 .../ObjectAdapterContext_NewIdentifier.java        | 129 ++++++++++++++++++++
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 132 +++++++++++----------
 .../ObjectAdapterContext_ServiceLookup.java        | 109 +++++++++++++++++
 10 files changed, 402 insertions(+), 217 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index fef5bf7..3b8e0ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -37,11 +37,11 @@ public interface ObjectAdapterProvider {
     
     // -- INTERFACE
 
-    /**
-     * @param pojo
-     * @return oid for the given domain object 
-     */
-    Oid oidFor(Object domainObject);
+//    /**
+//     * @param pojo
+//     * @return oid for the given domain object 
+//     */
+//    Oid oidFor(Object domainObject);
     
     /**
      * @return standalone (value) or root adapter
@@ -86,10 +86,10 @@ public interface ObjectAdapterProvider {
         @Programmatic
         ObjectAdapterProvider getObjectAdapterProvider();
         
-        @Programmatic
-        default Oid oidFor(Object domainObject) {
-            return getObjectAdapterProvider().oidFor(domainObject);
-        }
+//        @Programmatic
+//        default Oid oidFor(Object domainObject) {
+//            return getObjectAdapterProvider().oidFor(domainObject);
+//        }
         
         @Programmatic
         default ObjectAdapter adapterFor(Object domainObject) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index c345f38..444211e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -213,6 +214,13 @@ public class ServicesInjector implements ApplicationScopedComponent {
         return Collections.unmodifiableList(services);
     }
     
+    /**
+     * @return Stream of all currently registered service instances.
+     */
+    public Stream<Object> streamRegisteredServiceInstances() {
+        return services.stream();
+    }
+    
     // -- INJECT SERVICES INTO
 
     /**
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
index d22ef39..e5e0b8c 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
@@ -1175,7 +1175,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
             
         } else {
-            originalOid = createPersistentOrViewModelOid(pojo);
+            originalOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             ObjectAdapter adapter;
             
@@ -1200,70 +1200,13 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return objectAdapterContext.lookupAdapterFor(pojo);
     }
 
-    // -- create...Oid (main API)
-    /**
-     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
-     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
-     */
     @Override
-    public final RootOid createTransientOrViewModelOid(final Object pojo) {
-        return newIdentifier(pojo, Type.TRANSIENT);
-    }
-
-    /**
-     * Return an equivalent {@link RootOid}, but being persistent.
-     *
-     * <p>
-     * It is the responsibility of the implementation to determine the new unique identifier.
-     * For example, the generator may simply assign a new value from a sequence, or a GUID;
-     * or, the generator may use the oid to look up the object and inspect the object in order
-     * to obtain an application-defined value.
-     *
-     * @param pojo - being persisted
-     */
-    @Override
-    public final RootOid createPersistentOrViewModelOid(Object pojo) {
-        return newIdentifier(pojo, Type.PERSISTENT);
-    }
-
-    private RootOid newIdentifier(final Object pojo, final Type type) {
-        final ObjectSpecification spec = objectSpecFor(pojo);
-        if(spec.isService()) {
-            return newRootId(spec, SERVICE_IDENTIFIER, type);
-        }
-
-        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
-        final String identifier =
-                recreatableObjectFacet != null
-                ? recreatableObjectFacet.memento(pojo)
-                        : newIdentifierFor(pojo, type);
-
-                return newRootId(spec, identifier, type);
-    }
-
-    private String newIdentifierFor(final Object pojo, final Type type) {
-        return type == Type.TRANSIENT
+    public String identifierFor(final Object pojo, final Oid.State type) {
+        return type == Oid.State.TRANSIENT
                 ? UUID.randomUUID().toString()
                         : JdoObjectIdSerializer.toOidIdentifier(getPersistenceManager().getObjectId(pojo));
     }
 
-    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Type type) {
-        final Oid.State state =
-                spec.containsDoOpFacet(ViewModelFacet.class)
-                ? Oid.State.VIEWMODEL
-                        : type == Type.TRANSIENT
-                        ? Oid.State.TRANSIENT
-                                : Oid.State.PERSISTENT;
-        final ObjectSpecId objectSpecId = spec.getSpecId();
-        return new RootOid(objectSpecId, identifier, state);
-    }
-
-    private ObjectSpecification objectSpecFor(final Object pojo) {
-        final Class<?> pojoClass = pojo.getClass();
-        return getSpecificationLoader().loadSpecification(pojoClass);
-    }
-
-
 
     /**
      * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
@@ -1313,7 +1256,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
         if (rootOid.isTransient()) {
             // persisting
-            final RootOid persistentOid = createPersistentOrViewModelOid(pojo);
+            final RootOid persistentOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             objectAdapterContext.remapAsPersistent(adapter, persistentOid, this);
 
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
index 8fdeef5..e77e5fb 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
@@ -1167,7 +1167,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
             
         } else {
-            originalOid = createPersistentOrViewModelOid(pojo);
+            originalOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             ObjectAdapter adapter;
             
@@ -1192,70 +1192,13 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return objectAdapterContext.lookupAdapterFor(pojo);
     }
 
-    // -- create...Oid (main API)
-    /**
-     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
-     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
-     */
     @Override
-    public final RootOid createTransientOrViewModelOid(final Object pojo) {
-        return newIdentifier(pojo, Type.TRANSIENT);
-    }
-
-    /**
-     * Return an equivalent {@link RootOid}, but being persistent.
-     *
-     * <p>
-     * It is the responsibility of the implementation to determine the new unique identifier.
-     * For example, the generator may simply assign a new value from a sequence, or a GUID;
-     * or, the generator may use the oid to look up the object and inspect the object in order
-     * to obtain an application-defined value.
-     *
-     * @param pojo - being persisted
-     */
-    @Override
-    public final RootOid createPersistentOrViewModelOid(Object pojo) {
-        return newIdentifier(pojo, Type.PERSISTENT);
-    }
-
-    private RootOid newIdentifier(final Object pojo, final Type type) {
-        final ObjectSpecification spec = objectSpecFor(pojo);
-        if(spec.isService()) {
-            return newRootId(spec, SERVICE_IDENTIFIER, type);
-        }
-
-        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
-        final String identifier =
-                recreatableObjectFacet != null
-                ? recreatableObjectFacet.memento(pojo)
-                        : newIdentifierFor(pojo, type);
-
-                return newRootId(spec, identifier, type);
-    }
-
-    private String newIdentifierFor(final Object pojo, final Type type) {
-        return type == Type.TRANSIENT
+    public String identifierFor(final Object pojo, final Oid.State type) {
+        return type == Oid.State.TRANSIENT
                 ? UUID.randomUUID().toString()
                         : JdoObjectIdSerializer.toOidIdentifier(getPersistenceManager().getObjectId(pojo));
     }
 
-    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Type type) {
-        final Oid.State state =
-                spec.containsDoOpFacet(ViewModelFacet.class)
-                ? Oid.State.VIEWMODEL
-                        : type == Type.TRANSIENT
-                        ? Oid.State.TRANSIENT
-                                : Oid.State.PERSISTENT;
-        final ObjectSpecId objectSpecId = spec.getSpecId();
-        return new RootOid(objectSpecId, identifier, state);
-    }
-
-    private ObjectSpecification objectSpecFor(final Object pojo) {
-        final Class<?> pojoClass = pojo.getClass();
-        return getSpecificationLoader().loadSpecification(pojoClass);
-    }
-
-
 
     /**
      * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
@@ -1305,7 +1248,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
         if (rootOid.isTransient()) {
             // persisting
-            final RootOid persistentOid = createPersistentOrViewModelOid(pojo);
+            final RootOid persistentOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             objectAdapterContext.remapAsPersistent(adapter, persistentOid, this);
 
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
index 492857b..f5054f0 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
@@ -82,7 +82,13 @@ class PersistenceSession5_Decouple  {
     public ObjectAdapter adapterFor(
             final RootOid rootOid,
             final ConcurrencyChecking concurrencyChecking) {
-
+        
+        //FIXME[ISIS-1976] guard against service lookup
+        final ObjectAdapter serviceAdapter = objectAdapterContext.lookupServiceAdapterFor(rootOid);
+        if (serviceAdapter != null) {
+            return serviceAdapter;
+        }
+        
         // attempt to locate adapter for the Oid
         ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(rootOid);
         if (adapter == null) {
@@ -98,6 +104,14 @@ class PersistenceSession5_Decouple  {
             } catch(ObjectNotFoundException ex) {
                 throw ex; // just rethrow
             } catch(RuntimeException ex) {
+                
+                System.err.println("------------------------------------------");
+                System.err.println("rootOid: "+rootOid.enString());
+                
+                ex.printStackTrace();
+                System.err.println("------------------------------------------");
+
+                
                 throw new PojoRecreationException(rootOid, ex);
             }
         }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 1df596c..f0850e5 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -29,6 +29,7 @@ import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.Oid.State;
 import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
@@ -89,9 +90,6 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
 
     void close();
 
-    RootOid createTransientOrViewModelOid(Object pojo);
-    RootOid createPersistentOrViewModelOid(Object pojo);
-
     ObjectAdapter createTransientInstance(ObjectSpecification spec);
 
     ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento);
@@ -108,6 +106,14 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
     IsisConfiguration getConfiguration();
 
     PersistenceManager getPersistenceManager();
+    
+    /**
+     * @param pojo
+     * @param type
+     * @return String representing an object's id.
+     * @since 2.0.0-M2
+     */
+    String identifierFor(Object pojo, State type);
 
     /**
      * Convenient equivalent to {@code getPersistenceManager()}.
@@ -169,4 +175,6 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
     boolean isDestroyed(Object pojo);
 
 
+
+
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index a665d20..b204e36 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
-import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
@@ -144,6 +143,8 @@ public class ObjectAdapterContext {
     private final ObjectAdapterContext_ObjectAdapterProvider objectAdapterProviderMixin;
     private final ObjectAdapterContext_AdapterManager adapterManagerMixin;
     private final ObjectAdapterContext_MementoSupport mementoSupportMixin;
+    private final ObjectAdapterContext_ServiceLookup serviceLookupMixin;
+    private final ObjectAdapterContext_NewIdentifier newIdentifierMixin;
     
     private ObjectAdapterContext(
             ServicesInjector servicesInjector, 
@@ -155,6 +156,8 @@ public class ObjectAdapterContext {
         this.objectAdapterProviderMixin = new ObjectAdapterContext_ObjectAdapterProvider(this, persistenceSession);
         this.adapterManagerMixin = new ObjectAdapterContext_AdapterManager(this, persistenceSession);
         this.mementoSupportMixin = new ObjectAdapterContext_MementoSupport(this, persistenceSession);
+        this.serviceLookupMixin = new ObjectAdapterContext_ServiceLookup(this, servicesInjector);
+        this.newIdentifierMixin = new ObjectAdapterContext_NewIdentifier(this, persistenceSession);
         
         this.persistenceSession = persistenceSession;
         this.servicesInjector = servicesInjector;
@@ -166,15 +169,25 @@ public class ObjectAdapterContext {
                 persistenceSession);
     }
 
+    // -- DEBUG
+    
+    private void printContextInfo(String msg) {
+        String id = Integer.toHexString(this.hashCode());
+        String session = ""+persistenceSession;
+        System.out.println("!!!!!!!!!!!!!!!!!!!!!!! "+String.format("%s id=%s session='%s'", 
+                msg, id, session));
+    }
+    
     // -- LIFE-CYCLING
     
     public void open() {
+        printContextInfo("OPEN_");
         cache.open();
-        initServices();
     }
     
     public void close() {
         cache.close();
+        printContextInfo("CLOSE");
     }
     
     // -- CACHING POJO
@@ -220,6 +233,22 @@ public class ObjectAdapterContext {
         consistencyMixin.ensureMapsConsistent(oid);
     }
     
+    // -- NEW IDENTIFIER
+    
+    RootOid createTransientOrViewModelOid(final Object pojo) {
+        return newIdentifierMixin.createTransientOrViewModelOid(pojo);
+    }
+
+    public RootOid createPersistentOrViewModelOid(Object pojo) {
+        return newIdentifierMixin.createPersistentOrViewModelOid(pojo);
+    }
+    
+    // -- SERVICE LOOKUP
+    
+    public ObjectAdapter lookupServiceAdapterFor(RootOid rootOid) {
+        return serviceLookupMixin.serviceAdapterFor(rootOid);
+    }
+    
     // -- FACTORIES
     
     // package private
@@ -331,20 +360,20 @@ public class ObjectAdapterContext {
     
     // ------------------------------------------------------------------------------------------------
     
-    /**
-     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
-     * and have the same OIDs as in any previous sessions.
-     * 
-     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
-     */
-    @Deprecated
-    private void initServices() {
-        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
-        for (final Object service : registeredServices) {
-            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
-            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
-        }
-    }
+//    /**
+//     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
+//     * and have the same OIDs as in any previous sessions.
+//     * 
+//     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
+//     */
+//    @Deprecated
+//    private void initServices() {
+//        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
+//        for (final Object service : registeredServices) {
+//            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
+//            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+//        }
+//    }
     
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
             final ObjectSpecification objectSpecification = 
@@ -479,7 +508,7 @@ public class ObjectAdapterContext {
         return newAdapter;
     }
 
-    
+   
 
 
 }
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java
new file mode 100644
index 0000000..31995e8
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java
@@ -0,0 +1,129 @@
+/*
+ *  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 org.apache.isis.core.runtime.system.persistence.adaptermanager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+
+/**
+ * package private mixin for ObjectAdapterContext
+ * <p>
+ * Responsibility: creates RootOids 
+ * </p> 
+ * @since 2.0.0-M2
+ */
+@SuppressWarnings("unused")
+class ObjectAdapterContext_NewIdentifier {
+    
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_NewIdentifier.class);
+    private final ObjectAdapterContext objectAdapterContext;
+    private final PersistenceSession persistenceSession;
+    private final ServicesInjector servicesInjector;
+    private final SpecificationLoader specificationLoader;
+    
+    
+    ObjectAdapterContext_NewIdentifier(ObjectAdapterContext objectAdapterContext,
+            PersistenceSession persistenceSession) {
+        this.objectAdapterContext = objectAdapterContext;
+        this.persistenceSession = persistenceSession;
+        this.servicesInjector = persistenceSession.getServicesInjector();
+        this.specificationLoader = servicesInjector.getSpecificationLoader();
+    }
+    
+//    RootOid rootOidFor(Object pojo) {
+//        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
+//                ? createPersistentOrViewModelOid(pojo) 
+//                        : createTransientOrViewModelOid(pojo);
+//        
+//                
+//        return rootOid;
+//    }
+    
+    
+    // -- create...Oid (main API)
+    /**
+     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
+     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
+     */
+    final RootOid createTransientOrViewModelOid(final Object pojo) {
+        return newIdentifier(pojo, Oid.State.TRANSIENT);
+    }
+
+    /**
+     * Return an equivalent {@link RootOid}, but being persistent.
+     *
+     * <p>
+     * It is the responsibility of the implementation to determine the new unique identifier.
+     * For example, the generator may simply assign a new value from a sequence, or a GUID;
+     * or, the generator may use the oid to look up the object and inspect the object in order
+     * to obtain an application-defined value.
+     *
+     * @param pojo - being persisted
+     */
+    final RootOid createPersistentOrViewModelOid(Object pojo) {
+        return newIdentifier(pojo, Oid.State.PERSISTENT);
+    }
+
+    RootOid newIdentifier(final Object pojo, final Oid.State type) {
+        final ObjectSpecification spec = objectSpecFor(pojo);
+        if(spec.isService()) {
+            return newRootId(spec, PersistenceSession.SERVICE_IDENTIFIER, Oid.State.PERSISTENT); // services are always persistent
+        }
+
+        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
+        final String identifier =
+                recreatableObjectFacet != null
+                ? recreatableObjectFacet.memento(pojo)
+                        : persistenceSession.identifierFor(pojo, type);
+
+                return newRootId(spec, identifier, type);
+    }
+    
+    
+    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Oid.State type) {
+        final Oid.State state =
+                spec.containsDoOpFacet(ViewModelFacet.class)
+                ? Oid.State.VIEWMODEL
+                        : type == Oid.State.TRANSIENT
+                        ? Oid.State.TRANSIENT
+                                : Oid.State.PERSISTENT;
+        final ObjectSpecId objectSpecId = spec.getSpecId();
+        return new RootOid(objectSpecId, identifier, state);
+    }
+    
+    // -- HELPER
+    
+    private ObjectSpecification objectSpecFor(final Object pojo) {
+        final Class<?> pojoClass = pojo.getClass();
+        return specificationLoader.loadSpecification(pojoClass);
+    }
+
+
+    
+}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 593ad6c..a8f33ce 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -20,11 +20,13 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
 import java.util.List;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
@@ -47,6 +49,7 @@ import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
  */
 class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvider {
     
+    @SuppressWarnings("unused")
     private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_ObjectAdapterProvider.class);
     private final ObjectAdapterContext objectAdapterContext;
     private final PersistenceSession persistenceSession;
@@ -63,20 +66,19 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         this.isisJdoMetamodelPlugin = IsisJdoMetamodelPlugin.get();
     }
 
-    @Override
-    public Oid oidFor(Object pojo) {
-        if(pojo == null) {
-            return null;
-        }
-        final Oid persistentOrValueOid = persistentOrValueOid(pojo);
-        if(persistentOrValueOid != null) {
-            return persistentOrValueOid;
-        }
-        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
-                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
-                        : persistenceSession.createTransientOrViewModelOid(pojo);
-        return rootOid;
-    }
+//    @Override
+//    public Oid oidFor(Object pojo) {
+//        if(pojo == null) {
+//            return null;
+//        }
+//        final Oid persistentOrValueOid = persistentOrValueOid(pojo);
+//        if(persistentOrValueOid != null) {
+//            return persistentOrValueOid;
+//        }
+//        final RootOid rootOid = objectAdapterContext.rootOidFor(pojo);
+//        
+//        return rootOid;
+//    }
     
     @Override
     public ObjectAdapter adapterFor(Object pojo) {
@@ -89,16 +91,14 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
             return existingOrValueAdapter;
         }
 
-        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
-                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
-                        : persistenceSession.createTransientOrViewModelOid(pojo);
+        final RootOid rootOid = objectAdapterContext.createTransientOrViewModelOid(pojo);
         
-//        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
         final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
 
         return objectAdapterContext.mapAndInjectServices(newAdapter);
     }
-
+    
+    
     @Override
     public ObjectAdapter adapterFor(Object pojo, ObjectAdapter parentAdapter, OneToManyAssociation collection) {
 
@@ -140,66 +140,68 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
             return null;
         }
-        final RootOid oid = persistenceSession.createPersistentOrViewModelOid(pojo);
+        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
         final ObjectAdapter adapter = objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
         return adapter;
     }
     
+    private List<ObjectAdapter> initServiceAdapters() {
+        return servicesInjector.streamRegisteredServiceInstances()
+        .map(this::adapterFor)
+        .peek(serviceAdapter->{
+            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+        })
+        .collect(Collectors.toList());
+    }
+    
+    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
+    
     @Override
     public List<ObjectAdapter> getServices() {
-        final List<Object> services = servicesInjector.getRegisteredServices();
-        final List<ObjectAdapter> serviceAdapters = _Lists.newArrayList();
-        for (final Object servicePojo : services) {
-            ObjectAdapter serviceAdapter = objectAdapterContext.lookupAdapterFor(servicePojo);
-            if(serviceAdapter == null) {
-                throw new IllegalStateException("ObjectAdapter for service " + servicePojo + " does not exist?!?");
-            }
-            serviceAdapters.add(serviceAdapter);
-        }
-        return serviceAdapters;
+        return serviceAdapters.get();
     }
     
     // -- HELPER
     
-    private Oid persistentOrValueOid(Object pojo) {
-        
-        Oid oid;
-
-        // equivalent to  isInstanceOfPersistable = pojo instanceof Persistable;
-        final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
-        
-        // pojo may have been lazily loaded by object store, but we haven't yet seen it
-        if (isInstanceOfPersistable) {
-            oid = persistentOid(pojo);
-
-            // TODO: could return null if the pojo passed in !dnIsPersistent() || !dnIsDetached()
-            // in which case, we would ought to map as a transient object, rather than fall through and treat as a value?
-        } else {
-            oid = null;
-        }
-
-        if(oid != null) {
-            return oid;
-        }
-        
-        // need to create (and possibly map) the adapter.
-        final ObjectSpecification objSpec = specificationLoader.loadSpecification(pojo.getClass());
-
-        // we create value facets as standalone (so not added to maps)
-        if (objSpec.containsFacet(ValueFacet.class)) {
-            //TODO[ISIS-1976] don't need an adapter, just its oid
-            oid = objectAdapterContext.getFactories().createStandaloneAdapter(pojo).getOid(); 
-            return oid;
-        }
-
-        return null;
-    }
+//    private Oid persistentOrValueOid(Object pojo) {
+//        
+//        Oid oid;
+//
+//        // equivalent to  isInstanceOfPersistable = pojo instanceof Persistable;
+//        final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
+//        
+//        // pojo may have been lazily loaded by object store, but we haven't yet seen it
+//        if (isInstanceOfPersistable) {
+//            oid = persistentOid(pojo);
+//
+//            // TODO: could return null if the pojo passed in !dnIsPersistent() || !dnIsDetached()
+//            // in which case, we would ought to map as a transient object, rather than fall through and treat as a value?
+//        } else {
+//            oid = null;
+//        }
+//
+//        if(oid != null) {
+//            return oid;
+//        }
+//        
+//        // need to create (and possibly map) the adapter.
+//        final ObjectSpecification objSpec = specificationLoader.loadSpecification(pojo.getClass());
+//
+//        // we create value facets as standalone (so not added to maps)
+//        if (objSpec.containsFacet(ValueFacet.class)) {
+//            //TODO[ISIS-1976] don't need an adapter, just its oid
+//            oid = objectAdapterContext.getFactories().createStandaloneAdapter(pojo).getOid(); 
+//            return oid;
+//        }
+//
+//        return null;
+//    }
     
     protected Oid persistentOid(final Object pojo) {
         if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
             return null;
         }
-        final RootOid oid = persistenceSession.createPersistentOrViewModelOid(pojo);
+        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
         return oid;
     }
     
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
new file mode 100644
index 0000000..31d3b39
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -0,0 +1,109 @@
+/*
+ *  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 org.apache.isis.core.runtime.system.persistence.adaptermanager;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.context._Context;
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+
+/**
+ * package private mixin for ObjectAdapterContext
+ * <p>
+ * Responsibility: provides ObjectAdapters for registered services 
+ * </p> 
+ * @since 2.0.0-M2
+ */
+@SuppressWarnings("unused")
+class ObjectAdapterContext_ServiceLookup {
+    
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_ServiceLookup.class);
+    private final ObjectAdapterContext objectAdapterContext;
+    private final ServicesInjector servicesInjector;
+    
+    ObjectAdapterContext_ServiceLookup(ObjectAdapterContext objectAdapterContext,
+            ServicesInjector servicesInjector) {
+        this.objectAdapterContext = objectAdapterContext;
+        this.servicesInjector = servicesInjector;
+    }
+
+    ObjectAdapter serviceAdapterFor(RootOid rootOid) {
+        
+        final ServicesByIdResource servicesByIdResource =
+                _Context.computeIfAbsent(ServicesByIdResource.class, cls->initLookupResource());
+        
+        try {
+            final Object serviceInstance = servicesByIdResource.lookupServiceInstance(rootOid);
+            if(serviceInstance==null) {
+                return null;
+            }
+            return objectAdapterContext.getFactories().createRootAdapter(serviceInstance, rootOid);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new IllegalStateException("Could not resolve service for id '" + rootOid.enStringNoVersion() + "'");
+        }
+        
+    }
+    
+    // -- HELPER
+    
+    /**
+     *  Application scoped resource to hold a map for looking up services by id.
+     */
+    private static class ServicesByIdResource implements AutoCloseable {
+        private final Map<RootOid, Object> servicesById = _Maps.newHashMap();
+
+        @Override
+        public void close() {
+            servicesById.clear();
+        }
+
+        public Object lookupServiceInstance(RootOid serviceRootOid) {
+            return servicesById.get(serviceRootOid);
+        }
+    }
+    
+    private ServicesByIdResource initLookupResource() {
+        
+        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! INIT SERVICE ID LOOKUP RESOURCE");
+        
+        final ServicesByIdResource lookupResource = new ServicesByIdResource();
+        
+        servicesInjector.streamRegisteredServiceInstances()
+        .map(objectAdapterContext.getObjectAdapterProvider()::adapterFor)
+        .forEach(serviceAdapter->{
+            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+            lookupResource.servicesById.put((RootOid)serviceAdapter.getOid() , serviceAdapter.getObject());
+        });
+        
+        return lookupResource;
+    }
+    
+
+}
\ No newline at end of file