Skip to content

Verteilte Event Based Components mit Zyan erstellen

yallie edited this page May 21, 2018 · 1 revision

Was sind Event Based Components?

Es handelt sich dabei um Architekturmodell, welches direkte Abhängigkeit reduzieren und die Zusammensteckbarkeit von Komponenten erhöhen soll. Event Based Components (EBC) kommunizieren miteinander über Nachrichten, statt direkt Methoden aufzurufen. Eine Nachricht kann ein beliebiger .NET Typ sein (z.B. ein String oder ein eigenes komplexes Objekt). Die einzelnen Komponenten in einer EBC-Anwendung werden über sog. Pins miteinander "verdrahtet". Es wird zwischen Eingangs- und Ausgangspins unterschieden. Nachrichten fließen stets von einem Ausgangspin zu einem Eingangspin. Ausgangspins werden im Code durch Delegaten und Eingangspins durch Methoden abgebildet.

Eine einzelne EBC besteht aus folgenden Bestandteilen:

  • Nachrichtenklassen für den Datenaustausch (Müssen serialisierbar sein, damit übers Netzwerk übertragbar)
  • Komponenten-Schnittstelle (wichtig für Proxy-Generierung auf entfernten Clients)
  • Komponenten-Implementierung (muss die Komponenten-Schnittstelle implementieren)

Schnittstelle und Nachrichtenklassen müssen in eine Assembly gepackt werden, die Client und Server gleichermaßen bekannt sind (Shared-Assembly). Die eigentliche Komponenten-Implementierung kann entweder direkt in der Assembly des Server-Prozesses (Server-Assembly) oder in einer separaten Assembly untergebracht werden, die nur dem Server bekannt ist.

Am folgenden Beispiel eines sehr einfaches Additions-Rechners, sieht man, wie EBCs aufgebaut sind.

+Shared-Assembly+

{code:c#} // Nachrichtenklasse für Additionsanfrage Serializable public class AdditionRequestMessage { public decimal Number1 { get; set; }

public decimal Number2 { get; set; }

}

// Komponentenschnittstelle public interface ICalculator { void AddNumbers(AdditionRequestMessage request);

Action<decimal> Out_SendResult { get; set; }

} {code:c#} +Server-Assembly+

{code:c#} // Komponenten-Implementierung public class Calculator : ICalculator { // Eingangspin (Nimmt Zahlen für die Addition entgegen) public void AddNumbers(AdditionRequestMessage request) { decimal result = request.Number1 + request.Number2;

    if (Out_SendResult!=null)
        Out_SendResult(result);
}

// Ausgangspin (Sendet das Ergebnis der Addition zurück)
public Action<decimal> Out_SendResult { get; set; }

} {code:c#}

EBC hosten

Damit die EBC Calculator von entfernten Clients konsumiert werden kann, muss sie zunächst mit Zyan gehostet werden. Dies funktioniert ganz genauso, wie mit herkömmlichen Klassen auch.

{code:c#} ZyanComponentHost host = new ZyanComponentHost("CalculatorApp",8080); host.RegisterComponent<ICalculator, Calculator>(ActivationType.SingleCall); {code:c#}

EBC konsumieren

Auf der Clientseite lebende EBCs werden einfach mit den Proxies entfernter EBCs verdrahtet. Ganz genauso, wie man auch lokale EBCs miteinander verdrahten würde. Angenommen wir haben eine clientseitige EBC, die eine Benutzeroberfläche für die entfernte Calculator EBC als Windows.Forms-Formular implementiert. Auf dem Formular sind folgende Steuerelemente platziert:

||Membervariable||Beschreibung|| |_textNumber1|Textfeld für die 1. Zahl| |_textNumber2|Textfeld für die 2. Zahl| |_buttonCalc|Knopf, der die Berechnung startet| |_textResult|Textfeld für das Ergebnis| Der Code des Formulars sieht folgendermaßen aus:

+Client-Assembly+

{code:c#} public partial class CalcForm : Form { // Ausgangspin (Sendet die zu addierenden Zahlen an die Berechnungskomponente) public Action Out_AddNumbers { get; set; }

public CalcForm() 
{
    InitializeComponents();
}

private void _buttonCalc_Click(object sender, EventArgs e)
{
    if (Out_AddNumbers!=null)
        Out_AddNumbers(new AdditionRequestMessage() 
        {
            Number1 = decimal.Parse(_textNumber1.Text),
            Number2 = decimal.Parse(_textNumber2.Text)
        });
}

// Eingangspin (Empfängt das Ergebnis)
public void ReceiveResult(decimal result)
{
    _textResult.Text = result.ToString();
}

} {code:c#} Damit die Nachrichten fließen können, müssen beide Komponenten noch verdrahtet werden.

{code:c#} static class Program { static void main() { ZyanConnection connection = new ZyanConnection("tcp://localhost:8080/CalcuatorApp");

    // Komponenten bzw. Proxies erzeugen
    ICalculator calculatorProxy = connection.CreateProxy<ICalculator>();
    CalcForm form = new CalcForm();

    // Verdrahten
    form.Out_AddNumbers = Asynchronizer<AdditionRequest>.WireUp(new Action<AdditionRequest>(proxy.In_AddNumbers));
    proxy.Out_SendResult = SyncContextSwitcher<decimal>.WireUp(new Action<decimal>(form.In_ReceiveResult));        

    System.Windows.Forms.Application.Run(form);
}

} {code:c#} Den kompletten Quellcode dieses Beispiels finden Sie in der Quellcodeverwaltung im Ordner Examples.

Detaillierte Informationen, Beispiele und Varianten des EBC-Konzepts, finden Sie im Weblog des EBC-Erfinders Ralf Westphal.