Next: , Up: Integrating code in other languages   [Contents]


3.8.1 Integrating code in C#

Creating instances of the required runtime libraries is done similar to how it is done in C++. In C#, it is easier in the sense that no additional files must be included on a per-file basis. Preparing the runtime libraries is done as follows:

using System;

namespace MyDznApp {
  class main {
    private dzn.Locator dznLoc;
    private dzn.Runtime dznRt;

    public static void Main() {
      dznLoc = new dzn.Locator();
      dznRt = new dzn.Runtime();

      dznLoc.set(dznRt);
    }
  }
}

Take note that Locator and Runtime are located in the dzn namespace. Depending on the execution semantics of your application, you may choose to define the objects within the scope of Main or outside the scope (as can be seen above).

Creating an object to represent the System generated from Dezyne models requires you to pass the dzn.Locator object you created as parameter:

using System;

namespace MyDznApp {
  class main {
    private dzn.Locator dznLoc;
    private dzn.Runtime dznRt;
    private AlarmSystem as;

    public static void Main() {
      dznLoc = new dzn.Locator();
      dznRt = new dzn.Runtime();

      dznLoc.set(dznRt);
      as = new AlarmSystem(dznLoc);
    }
  }
}

In C#, events are generated as Action or Func objects, the C# variant of function objects. Action is used for void on events; Func is used for on events that have a return value. To reach an event on a port of a component, the following structure is applied in generated C#:

ComponentName.PortName.PortDirection.EventName, where ComponentName is the name of the data object representing the Component, PortName is the name of the Port you are trying to access, PortDirection is either inport or outport depending on the specification and EventName is the name of the on event you are trying to access.

As an example, let’s invoke the validPincode event on the provided iController port of the AlarmSystem (required action for Provides/in and Requires/out):

using System;

namespace MyDznApp {
  class main {
    private dzn.Locator dznLoc;
    private dzn.Runtime dznRt;
    private AlarmSystem as;

    public static void Main() {
      dznLoc = new dzn.Locator();
      dznRt = new dzn.Runtime();

      dznLoc.set(dznRt);
      as = new AlarmSystem(as);

      as.iController.inport.validPincode();
    }
  }
}

Here, the ComponentName is as; PortName is iController; PortDirection is import; EventName is validPincode.

Let’s assume the provided IController port has an out event void foo(). According to the table in the introduction of this section, Provides/out and Requires/in require you to assign foreign code to a System function. void foo() will be represented as an Action object, which we must assign foreign code to. To assign to an Action object, we can use a lambda expression:

using System;

namespace MyDznApp {
  class main {
    private dzn.Locator dznLoc;
    private dzn.Runtime dznRt;
    private AlarmSystem as;

    public static void Main() {
      dznLoc = new dzn.Locator();
      dznRt = new dzn.Runtime();

      dznLoc.set(dznRt);
      as = new AlarmSystem(as);
      as.iController.outport.foo = () => { /* Foreign implementation of foo() */};

      as.iController.inport.validPincode();
    }
  }
}

For more information on lambda expressions in C#, please refer to https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions.


Next: , Up: Integrating code in other languages   [Contents]