Erweiterte Programmierung


Bei klassischer .NET-Programmierung werden Objekte durch Zuweisung einer Eigenschaft referenziert. Der .NET Garbage Collector kann das Objekt erst dann aus dem Speicher entfernen wenn es keine Referenzen mehr darauf gibt.

Mehr dazu unter:

Dieses Konzept der "festen Referenzen" hat einige Nachteile im Zusammenhang mit dem Konzept der netzwerk-transparenten Programmierung in iPlus:

  1. Serialisierung von Referenzen: Das Konzept der Netzwerktransparenten Programmierung beruht darauf, dass ihr Programmcode so programmiert ist, dass sie selbst nicht wissen müssen, ob die Instanz mit der Sie arbeiten ein Proxy ist oder nicht. Demzufolge müssen auch Referenzen die serverseitig auf andere Instanzen (reele Objekte) verweisen auch auf der Proxy-Seite verfügbar sein. Quasi eine automatische Übertragung der Referenzen über das Netzwerk (von einer Anwendungsdomäne zur anderen).
  2. Deabonnement vor Garbage-Collection: Solange eine Proxy-Instanz referenziert wird, muss der Server die Werte von netzwerkfähigen Eigenschaften einer reelen Instanz (auf serverseite) bei Änderungsereignissen zur Proxy-Instanz senden. Umgekehrt, wenn eine Proxy-Instanz nicht mehr in der Anwendungsdomäne des Clients referenziert wird (sei es von der GUI oder vom Anwendungsmodell), soll der Server keine Daten mehr an diese Proxy-Instanz verteilen. Das bedeutet, bevor der .NET-Garbage-Collector ins Spiel kommt, um die Proxy-Instanz aus dem Speicher zu entfernen, muss automatisch im Hintergrund
    • eine Deabonnier-Nachricht an den Server gesendet,
    • die Deinitialisierung der Proxy-Instanz eingeleitet,
    • und ggf. die Proxy-Instanz gepoolt
      werden.
  3. Reinitialisierung: Eine klassische .NET-Referenz kann nicht automatisch durch eine neue Objektinstanz ausgetauscht werden. Mit dem Konzept der Reinitialisierung in iPlus ist dies jedoch zwingend erforderlich. Eine Reinitialisierung bedeutet, dass eine neue ACComponent-Instanz erzeugt und mit einer alten ausgetauscht wird. In diesem Fall müssen im Hintergrund alle Referenzen, die auf diese alte Instanz referenzieren mit der neuen ausgetauscht werden.
  4. Netzwerkübertragung von Datenbankreferenzen: Klassen des Entity-Frameworks implementieren auch das interface IACObject. Da ACComponent ebenfalls IACObject implementiert, sind beide aus abstrakter Sicht ein Objekt das referenziert und im Netzwerk verteilt werden kann (siehe Punkt 1). Ein komplexes Entity-Objekt zu serialisieren ist im Grunde unnötigt, weil die Proxy-Instanz auf Client-Seite eine Datenbankverbindung aufbauen kann und sich die Daten des entsprechenden Entity-Objekts selbst laden kann.

Die Klasse ACRef<T> ist ein intelligenter Zeiger, der die zuvor beschriebenen Punkte implementiert.

Aus diesen Gründen verwenden Sie immer diesen Smartpointer ACRef<T> wenn Sie Referenzen zu ACComponent-Instanzen über einen längeren Zeitraum hinweg halten möchten!

Jegliche interne Implementierungen im iPlus-Framework sind so programmiert, dass ACRef<T> verwendet wird.


ACRef<T> ist eine generische Klasse. Der Typ T beschreibt von welchem Typ das zu referenzierende Objekt ist.

Das wichtigste Merkmal einer ACRef<T> ist der Zustand "IsAttached" der beschreibt, ob das referenzierte Objekt getrennt oder verbunden ist. Im getrennten Zustand hält die ACRef keine .NET-Referenz zu dem gekapselten Objekt bzw. zu einer Instanz des generischen Typs T. Mit dem Zugriff auf die Eigenschaft ValueT oder Value wird das zu referenzierende objekt sofort wieder verbunden.

Damit eine ACRef<T> im getrennten Zustand weiß mit welchem Objekt sie verbunden war, wird entweder die ACUrl gespeichert oder der EntityKey.

 

Wesentliche Eigenschaften:

ParameterBeschreibung
T
ValueT

Referenziertes Objekt (Component oder Entität). Beim Zugriff auf diese Eigenschaft wird das referenzierte Objekt automatisch verbunden falls es sich im getrennten Zustand befindet.

object value

ValueT als object.

bool 
IsObjLoaded

Überprüft ob ValueT nicht null ist. Beim Zugriff auf diese Eigenschaft wird das referenzierte Objekt automatisch verbunden falls es sich im getrennten Zustand befindet.

bool IsAttached

Prüft ob das referenzierte Objekt sich im verbundenen Zustand befindet (Attached).

bool IsWeakReferenceEine schwache Referenz ist eine Referenz die nicht verhindert, dass das referenzierte Objekt von iPlus-GarbageCollector eingesammelt wird.
RefInitMode Mode

Steuert das Verhalten für den automatischen Start oder Stop einer referenzierten Komponente.

 public enum RefInitMode : short
{
NoInstantiation = 0,
AutoStart = 1,
AutoStop = 2,
AutoStartStop = 3,
}
IACObject ParentACObjectReferenz zur Eltern-Komponente, die diesen Smart-Pointer hält bzw. besitzt.
string ACUrlACUrl falls eine ACComponent oder IACObject referenziert wird.
EntityKey EntityKeyFalls das referenzierte Objekt eine Entität ist dann wird der EntityKey gespeichert.

 

Wesentliche Methoden:

MethodeBeschreibung
void Attach()

Verbindet das referenzierte Objekt falls es sich im getrennten Zustand befindet.

void Detach(bool detachFromContext = false)

Trennt das referenzierte T-Objekt und speichert die Referenzinformation in der ACUrl or EntityKey-Eigenschaft. Falls Parameter "detachFromContext" true gesetzt wird, dann wird das referenzierte Entity-Objekt auch von seinem Datenbankkontext getrennt.

void AttachTo(IACObject parentACObject)

Verbindet das gekapselte Objekt an das Eltern-Objekt das diesen intelligenten Zeiger hält bzw. besitzt. Für Entity-Objekte übergeben Sie stattdessen den Datenbankkontext.

 


Die Instanziierung eines Smart-Pointers erfolgt per new-Anweisung. Es gibt verschiedene Konstruktoren. Jedoch sollten immer die Konstruktoren verwendet werden bei denen das Eltern-Objekt übergeben werden muss. Das Eltern-Objekt gibt an wem der Smart-Pointer angehört. Bei Referenzen auf Entity-Objekte übergeben Sie den Datenbankkontext als Eltern-Objekt.

Referenzen, die nicht mehr benötigt werden, müssen mit der Methode Detach() getrennt werden. Getrennte Referenzen können mit der Methode Attach() wieder verbunden werden. Bei Entity-Objekten verwenden Sie bitte die AttachTo()-Methode, um den Datenbankkontext zu übergeben.

Hier einige Beispiele:

 

Damit Entity-Referenzen über das Netzwerk gesendet werden können, müssen sie vom DataContract-Serializer serialiisert werden. Deswegen müssen Sie diese mit der ACSerializableInfo-Attributklasse bekannt geben.


Wenn man umgekehrt wissen möchte welche Smartpointer auf eine ACComponent (this) verweisen, stellt eine ACComponent die Eigenschaft IACPointReference<IACObject> ReferencePoint zur Verfügung.

IACPointReference ist eine Ableitung vom interface IACPoint<T>das einen sogenannten Verbindungspunkt darstellt

Ein IACPoint<T> stellt die Eigenschaft IEnumerable<T> ConnectionList zu Verfügung, mit der man den ReferencePoint abfragen kann, um alle Smart-Pointer zu erhalten, die in Beziehung zur Komponente stehen:

var query = this.ReferencePoint.ConnectionList.Where(c => c is IACContainerRef);

IACContainerRef ist das Basis-Interface für das ACRef<T> um typneutral zugreifen zu können.

Weil die ConnectionList eines Referenzpunktes auch andere Beziehungen enthalten kann ist die obige Abfrage nach IACContainerRef notwendig. In der Regel möchte man jedoch nur wissen, ob die Komponente überhaupt noch referenziert wird oder nicht. Dies stellt die Eigenschaft "HasStrongReferences" bereit:

bool hasAnyRef = this.ReferencePoint.HasStrongReferences;

Diese Eigenschaft sucht in der Liste nach allen Smart-Pointern die keine schwache Referenz haben (IsWeakReference = false).