This sample showcases how one might build modules for Azure IoT Edge in .NET.
The sample contains:
- A printer module (C#) that interprets telemetry from sensor and prints its content and properties into Console.
- A sensor module (C#) that publishes random data to the gateway.
- A logger module for producing message broker diagnostics.
Other resources:
- Setup your Windows development machine. A guide for doing this can be found here.
- Make sure you have .NET Framework installed. Our current version of the binding was tested and loads modules written in .NET version v4.0.30319.
You can find the diagram for Receiving a message and publishing a message on this flow chart:
At this point, gateways containing .NET modules are only supported on Windows Desktop. The sample gateway gets built when you build Azure IoT Edge by first running
tools\build_dotnet.cmd
then running
tools\build.cmd --enable-dotnet-binding
The devbox setup guide has more information on how you can build Azure IoT Edge.
The build_dotnet.cmd
script builds the .NET Modules in the solution located here (../bindings/dotnet/dotnet-binding/dotnet-binding.sln).
Today the Solution has:
- Microsoft.Azure.IoT.Gateway ==> DLL you shall reference on your module project.
- Microsoft.Azure.IoT.Gateway.Test ==> Unit tests for the implementation of Message and Broker Classes.
- PrinterModule ==> .NET(C#) Module that output to the console content received by Sensor Module.
- Sensor Module ==> .NET(C#) Module that publishes Simulated Sensor data to the gateway.
Building the solution you will have the following binaries:
- Microsoft.Azure.IoT.Gateway.dll.
- SensorModule.dll.
- PrinterModule.dll.
Copy these binaries to the same folder you run your gateway.
- Open azure_iot_gateway_sdk solution and configure project
dotnet_binding_sample
as a Startup Sample. - Go to the Project Properties and change
Command Arguments
to point to dotnet_binding_sample.json. - Copy the following binaries to the folder:
build\samples\dotnet_binding_sample\Debug
:- Microsoft.Azure.IoT.Gateway.dll(and pdb if you want to debug).
- PrinterModule.dll.
- SensorModule.dll.
- Change the configuration Debugger Type to Mixed (this way you will be able to set breakpoints on Managed code as well as Native Code).
- Run.
{
"modules": [
{
"name": "logger",
"loader": {
"name": "native",
"entrypoint": {
"module.path": "..\\..\\..\\modules\\logger\\Debug\\logger.dll"
}
},
"args": { "filename": "C:\\Temp\\Log.txt" }
},
{
"name": "dotnet_sensor_module",
"loader": {
"name": "dotnet",
"entrypoint": {
"dotnet_module_path": "SensorModule",
"dotnet_module_entry_class": "SensorModule.DotNetSensorModule"
}
},
"args": "module configuration"
},
{
"name": "dotnet_printer_module",
"loader": {
"name": "dotnet",
"entrypoint": {
"dotnet_module_path": "PrinterModule",
"dotnet_module_entry_class": "PrinterModule.DotNetPrinterModule"
}
},
"args": "module configuration"
}
],
"links": [
{"source": "dotnet_sensor_module", "sink": "dotnet_printer_module" }
]
}
- Create a .NET project (DLL) (Class library).
- Add Reference to Microsoft.Azure.IoT.Gateway DLL.
- On your class you shall implement
IGatewayModule
. See the Printer module as example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.IoT.Gateway;
namespace PrinterModule
{
public class DotNetPrinterModule : IGatewayModule
{
private string configuration;
public void Create(Broker broker, byte[] configuration)
{
this.configuration = System.Text.Encoding.UTF8.GetString(configuration);
}
public void Destroy()
{
}
public void Receive(Message received_message)
{
if(received_message.Properties["source"] == "sensor")
{
Console.WriteLine("Printer Module received message from Sensor. Content: " + System.Text.Encoding.UTF8.GetString(received_message.Content, 0, received_message.Content.Length));
}
}
}
}
Modules may also implement the IGatewayModuleStart
interface. The Start method is called when the gateway's Broker is ready for the module to send and receive messages.
- Add your new module on Json configuration:
{
"modules" :
[
{
"module name" : "dotnet_printer_module", ==> Your new module name.
"loading args" : {
"module path" : "..\\..\\..\\bindings\\dotnet\\Debug\\dotnet.dll" ==> This is the location where the dotnet.dll is located.
}
"args" : {
"dotnet_module_path": "PrinterModule", ==> This is the name of your module dll. On this sample it is PrinterModule.dll
"dotnet_module_entry_class": "PrinterModule.DotNetPrinterModule", ==> This is the name of your Class (Namespace.ClassName) that implements IGatewayModule.
"dotnet_module_args": "module configuration" ==> This is any configuration you want to use on your sample. It will be passed to you as a byte[] that should be converted to an UTF-8 Encoded String, you can add a JSON configuration in it.
}
}
]
}