Click or drag to resize

eigene Views

Dieses Kapitel befasst sich mit besonderen, selbst erstellten View-Dlls. Über eigene Views können Sie die Darstellung von Checkern und deren Prüfungsergebnissen in Vishnu nahezu beliebig erweitern und verändern. Vishnu deckt mit seinen schon bereitgestellten Standard-Views alle wesentlichen Funktionalitäten ab. Wie Sie aber schon in ein einfaches Beispiel beim Job CheckDiskSpace sehen konnten, kann über eigene Views Information visuell noch viel eingänglicher aufbereitet werden. Für die Erstellung eigener DLLs sind jedoch Grundkenntnisse in einer DotNet-Sprache, z.B. C# erforderlich.

Wichtig  Wichtig

Der Einstieg ist allerdings für C# durch eine Vishnu-Visual Studio-Erweiterung auch ohne Programmierkenntnisse möglich. Es wird auf Knopfdruck ein lauffähiges Testprojekt mit Ihrer eigenen neuen View generiert.

der Demo Job

Dies ist die JobDescription.xml für den Demo-Job für eigene Views:

JobDescription.xml
<?xml version="1.0" encoding="utf-8"?>
<JobDescription>
  <LogicalName>UserViewDemo</LogicalName>
  <LogicalExpression>Predecessor AND UserChecker</LogicalExpression>
  <Checkers type="array">
    <Checker>
      <LogicalName>Predecessor</LogicalName>
      <PhysicalPath>TrueFalseExceptionChecker.dll</PhysicalPath>
      <Parameters>False:True:Exception|10|Predecessor: Hello World</Parameters>
      <Trigger>
        <PhysicalPath>TimerTrigger.dll</PhysicalPath>
        <Parameters>S:3|S:15</Parameters>
      </Trigger>
    </Checker>
    <Checker>
      <LogicalName>UserChecker</LogicalName>
      <PhysicalPath>Plugin\UserChecker.dll</PhysicalPath>
      <UserControlPath>Plugin\UserView.dll</UserControlPath>
      <Trigger>
        <Reference>True</Reference>
        <Parameters>Predecessor</Parameters>
      </Trigger>
    </Checker>
  </Checkers>
</JobDescription>

Den wesentlichen Unterschied zum Demo-Job für eigene Checker (siehe eigene Checker) macht die zusätzliche Anweisung <UserControlPath>Plugin\UserView.dll</UserControlPath>/<UserControlPath>Plugin\UserView.dll</UserControlPath>.

Hierüber wird Vishnu mitgeteilt, dass sich im Verzeichnis Plugin eine eigene DLL UserView.dll befindet, die Vishnu anstelle der Standard-View verwenden soll.

das Demo Projekt - schnell erzeugen

Über die Visual Studio Erweiterung Vishnu_UserView_VSIX.vsix (per Doppelklick installieren) können Sie Visual Studio eine C#-Projektvorlage für eigene Views hinzufügen:

Vishnu User View VSIX

Diese Projektvorlage kann dann später für ein neues Projekt verwendet werden:

Achtung  Achtung

Es erfolgen während der Generierung der Projekte zwei Fehlermeldungen, dass dem Projekt nicht alle erforderlichen Pakete hinzugefügt werden könnten. Diese treffen aber nicht zu und können ignoriert werden.

Vishnu User View VSIX select

Es wird eine Projektmappe mit einem View-Projekt und einem Testprojekt generiert.

User View Solution
Hinweis  Hinweis

Die UserView und das Testprojekt sind sofort lauffähig und die UserView kann mit der implementierten Demo-Funktionalität als Vishnu-View eingesetzt werden.

Hier die Ausgabe des Testprojekts im Debugger:

User View Demo Run
das Demo Projekt - Details

Die Klasse UserChecker_ReturnObject im durch die Projektvorlage generierten Projekt (s.o.) sollte normalerweise identisch zur ReturnObject-Klasse des entsprechenden Checkers aus dem passenden UserChecker-Projekt sein.

Hinweis  Hinweis

Wenn Sie später in eigenen Projekten die doppelte Definition des ReturnObjects vermeiden wollen, können Sie stattdessen auch mit einer Referenz auf die passende Checker.dll arbeiten. Um das Demo-Projekt einfach zu halten, wurde hier die UserChecker_ReturnObject.cs aus dem UserCheckerDemo-Projekt kopiert.

In der Klasse ResultViewModel müssen an zwei Stellen die darzustellenden Eigenschaften (Properties) des ReturnObjects eingefügt werden:

Auszug aus der Klasse ResultViewModel
    ...
// TODO: Hier müssen die darzustellenden Properties aus UserChecker_ReturnObject hinzugefügt werden:
/// <summary>
/// Demo-Property.
/// Das UserChecker_ReturnObject kann prinzipiell beliebige öffentliche Properties besitzen.
/// In diesem ViewModel werden nur Properties berücksichtigt, die in den Serialisierungs-
/// Deserialisierungsroutinen des UserCheckers entsprechend berücksichtigt wurden.
/// </summary>
public string DefaultResultProperty
{
    get
    {
        string prop = this.GetResultProperty<string>(typeof(UserChecker_ReturnObject), "DefaultResultProperty");
        return prop;
    }
}

    ...

/// <summary>
/// Wird ausgeführt, wenn sich die Result-Property des ViewModels
/// des zugehörigen Vishnu-Knotens geändert hat.
/// </summary>
public void HandleResultPropertyChanged()
{
            ...
    // TODO: Hier müssen die darzustellenden Properties aus UserChecker_ReturnObject hinzugefügt werden:
    this.RaisePropertyChanged("DefaultResultProperty");

    // TODO: Eventuelle zusätzliche Buttons müssten hier zum Update gezwungen werden,
    // da die Verarbeitung in einem anderen Thread läuft, z.B.:
    // this._btnXYZ...RelayCommand.UpdateCanExecuteState(this.Dispatcher);
}

    ...
Hinweis  Hinweis

Der Code-Auszug zeigt nur die absolut notwendigen Änderungen. Erweiterungen zum Beispiel für eigene Buttons sind in der Originalquelle angedeutet.

Serialisierung/De-Serialisierung

Bisher wurde ein Thema noch nicht behandelt, das für die korrekte Darstellung von Ergebnissen eigener Checker in eigenen Views unerlässlich ist: die Serialisierung und De-Serialisierung des UserChecker_ReturnObjectes.

Vishnu behandelt UserChecker_ReturnObjecte bei der Anzeige in den Standard-Views einfach als Zeichenketten. Dies ist aber für die Aufbereitung strukturierter Inhalte (Properties) unzureichend. Hierfür muss auf die Properties im Einzelnen zugegriffen werden können. Die Klasse UserChecker_ReturnObject enthält für diesen Zweck folgende Routinen (Überblick):

  • Deserialisierungs-Konstruktor

  • Serialisierungs-Hilfsroutine

  • Überschriebene ToString()-Methode

  • Überschriebene Vergleichsmethode

  • Überschriebene Hashcode Erzeugungsroutine

Alle fünf Routinen müssen vorhanden sein und in den oben fett gedruckten drei Routinen müssen die Properties von UserChecker_ReturnObjecten behandelt werden. Details sind im nachfolgenden Code-Auschnitt der UserChecker_ReturnObject-Klasse zu sehen:

Auszug aus der Klasse UserChecker_ReturnObject
    ...
/// <summary>
/// Deserialisierungs-Konstruktor.
/// </summary>
/// <param name="info">Property-Container.</param>
/// <param name="context">Übertragungs-Kontext.</param>
protected UserChecker_ReturnObject(SerializationInfo info, StreamingContext context)
{
    this.DefaultResultProperty = info.GetString("DefaultResultProperty");
}

/// <summary>
/// Serialisierungs-Hilfsroutine: holt die Objekt-Properties in den Property-Container.
/// </summary>
/// <param name="info">Property-Container.</param>
/// <param name="context">Serialisierungs-Kontext.</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("DefaultResultProperty", this.DefaultResultProperty);
}

/// <summary>
/// Überschriebene ToString()-Methode - stellt alle öffentlichen Properties
/// als einen aufbereiteten String zur Verfügung.
/// </summary>
/// <returns>Alle öffentlichen Properties als ein String aufbereitet.</returns>
public override string ToString()
{
    StringBuilder str = new StringBuilder(this.DefaultResultProperty);
    // str.Append(...);
    return str.ToString();
}

/// <summary>
/// Überschriebene Vergleichsmethode - vergleicht dieses Result mit
/// einem übergebenen Result nach Inhalt.
/// </summary>
/// <param name="obj">Das zu vergleichende Result.</param>
/// <returns>True, wenn das übergebene Result inhaltlich gleich diesem Result ist.</returns>
public override bool Equals(object obj)
{
    if (obj == null || this.GetType() != obj.GetType())
    {
        return false;
    }
    if (Object.ReferenceEquals(this, obj))
    {
        return true;
    }
    if (this.ToString() != obj.ToString())
    {
        return false;
    }
    return true;
}

/// <summary>
/// Überschriebene Hashcode Erzeugungsroutine - Erzeugt einen
/// eindeutigen Hashcode für dieses Result.
/// </summary>
/// <returns>Hashcode (int).</returns>
public override int GetHashCode()
{
    return (this.ToString()).GetHashCode();
}
    ...
Hinweis  Hinweis

Die Routinen zur Serialisierung, bzw. De-Serialisierung spielen übrigens auch bei der Darstellung von Snapshots eine wichtige Rolle.

Siehe auch