Referenzauflösung bei Instanziierung

Referenzen zwischen konfigurierten Instanzen können in der Konfiguration über ID- und Referenzproperties ausgedrückt werden. Beim Instanziieren einer typisierten Konfiguration können Referenzen (Querverweise) in ähnlicher Weise aufgelöst werden, wie auch Teilkonfigurationen instanziiert werden können.

ID-Property

Das Ziel der Referenz (die referenzierbare Instanz) muss hierfür ein Property deklarieren, das mit @Id markiert ist:

public class A {
   public interface Config extends PolymorphicConfiguration<A> {
      @Id(A.class)
      String getName();
   }

   public A(InstantiationContext context, Config config) {
      ...
   }
}

Referenz-Property

Eine Referenz auf eine Instanz von A kann dann über ein beliebiges anderes Property vom selben Typ wie das ID-Property realisiert werden:

public class B {
   public interface Config extends PolymorphicConfiguration<B> {
      String getRef();
   }
}

Referenz-Auflösung

Die Auflösung der so deklarierten Referenz muss im Config-Konstruktor von B erfolgen:

public class B {

   A _ref;

   public B(InstantiationContext context, Config config) {
      context.resolveReference(config.getRef(), A.class, 
         new ReferenceResolver<A>() {
            @Override
            public void setReference(A value) {
               _ref = value;
            }
      });
   }

Hierfür wird der Wert des Referenz-Properties zusammen mit einem Callback an den Instanziierungskontext übergeben. Sobald das Ziel der Referenz instanziiert wurde, wird dieses an den Callback übergeben und kann so in der Quelle die aufgelöste Referenz bekanntgeben.

Damit die Referenzauflösung funktionieren kann, müssen beide Beteiligte (die referenzierende Konfiguration und die referenzierte Konfiguration) in demselben Instanziierungskontext angelegt werden. Beispielsweise darf die Instanz von B selbst kein (oder Teil von einem) Instance-Format-Property sein. Ansonsten würde B instanziiert, wenn die Konfiguration gelesen wird. Zu diesem Zeitpunkt existiert aber die Instanz des referenzierten A noch nicht.

Wichtig: Es muss genau der Typ angegeben werden, in dessen ConfigItem die Annotation @Id(...) steht. Subklassen können NICHT verwendet werden. Folgendes funktioniert also zum Beispiel NICHT:

context.resolveReference(InstantiationContext.OUTER, FormComponent.class, ...);

Statt dessen muss bei Komponenten immer LayoutComponent angegeben werden:

context.resolveReference(InstantiationContext.OUTER, LayoutComponent.class, ...);

Umschließende Instanz

Eine Referenz auf die umgebende Instanz kann über die spezielle ID InstantiationContext.OUTER aufgelöst werden:

public class B {

   A _outer;

   public B(InstantiationContext context, Config config) {
      context.resolveReference(InstantiationContext.OUTER, A.class, 
         new ReferenceResolver<A>() {
            @Override
            public void setReference(A value) {
               _outer = value;
            }
      });
   }

In diesem Fall muss keine Referenz explizit konfiguriert werden. Allerdings muss die aufzulösende äußere Instanz ein ID-Property in ihrer Konfiguration deklarieren. Der Wert dieses ID-Properties spielt bei der Auflösung der OUTER-Referenz aber keine Rolle.

Mit diesem Mechanismus kann keine Referenz auf die Parent-Instanz desselben Typs aufgelöst werden. Wenn in A eine OUTER-Referenz auf den Typ A aufgelöst wird, wird eine Referenz auf die Instanz selbst (this) geliefert.

Siehe auch