Skip to content

Writing distributed Event Based Components

yallie edited this page May 21, 2018 · 1 revision

What is Event Based Components?

Event Based Components (EBC) is an architectural model which reduces dependencies between components. Components in EBC application communicate with each other by means of messages instead of invoking methods. Messages can be of any .NET type (such as string or some complex class). Components are wired together just like electronic components, pin to pin. Components may have input and output pins, and communication messages always flow from output pins to input pins. Technically, output pins are events and input pins are methods which take single message argument.

EBC communication requires the following:

  • Message types used for data transfer (should be serializable)
  • Component interfaces (used to generate client-side proxies)
  • Component classes (they should implement corresponding interfaces)

Interfaces and message types should be defined in the shared interface assembly known both to the client and the server (Shared Assembly). Component classes should be defined in an assembly which is only known to the server (Server-Assembly).

Here is a simple calculator example which shows how EBC applications could be built:

+Shared Assembly+

{code:c#} // Message type used by calculator EBC Serializable public class AdditionRequestMessage { public decimal Number1 { get; set; }

public decimal Number2 { get; set; }

}

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

Action<decimal> Out_SendResult { get; set; }

} {code:c#} +Server Assembly+

{code:c#} // EBC implementation public class Calculator : ICalculator { // Input pin (consumes addition request messages) public void AddNumbers(AdditionRequestMessage request) { decimal result = request.Number1 + request.Number2;

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

// Output pin (broadcasts addition result)
public Action<decimal> Out_SendResult { get; set; }

} {code:c#}

Hosting EBCs

To make EBC calculator available to clients, you need to host it in ZyanHost just like ordinary non-EBC components:

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

Consuming EBCs

Client-side EBCs can be wired to remote EBC proxies just the same way as to the local components. Let's suppose we want to consume EBC calculator in a simple Windows Forms application. We create a form and add a few input controls:

||Name||Description|| |_textNumber1|Text field for the first summand| |_textNumber2|Text field for the second summand| |_buttonCalc|Button which starts the calculation| |_textResult|Text field for the result|

Client code looks as follows:

+Client Assembly+

{code:c#} public partial class CalcForm : Form { // Output pin (to be wired to EBC calculator's input pin) public Action Out_AddNumbers { get; set; }

public CalcForm() 
{
    InitializeComponents();
}

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

// Input pin (to be wired with EBC calculator's output pin)
public void ReceiveResult(decimal result)
{
    _textResult.Text = result.ToString();
}

} {code:c#} Next, you must wire up two components (EBC calculator and input form) to enable message flow.

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

    // create EBC components and proxies
    var calculatorProxy = connection.CreateProxy<ICalculator>();
    var form = new CalcForm();

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

    // run the application
    System.Windows.Forms.Application.Run(form);
}

} {code:c#} Full source code for this example could be found in Examples folder.

Tip: For more information on EBC model, see EBC inventor Ralf Westphal's blog (German only) or check out brief Event-Based Components Overview written for codeplex EBC Tooling project.