# Dynamically map JSON commands to object methods in .Net

**Date:** 2016-08-21  
**Author:** Kees C. Bakker  
**Categories:** .NET Framework / C#  
**Original:** https://keestalkstech.com/dynamically-map-json-commands-object-methods-net/

![Dynamically map JSON commands to object methods in .Net](https://keestalkstech.com/wp-content/uploads/2016/08/photo-1470506926202-05d3fca84c9a.jpg)

---

Lately I've been playing around with USB led lights in .Net. I wanted the animations to be separated from my code. Wouldn't it be great if you could define *what animations* are executed in a JSON file? And map it to code?

Normally one would build a mapper that does the conversion of the JSON commands to the methods. I like to use a more generic approach. I've created a small utility class that executes commands by mapping and executing them as a method of the object. The solution is workable for a host of scenarios:

## Nuget

Before you start, there is a Nuget package. (Link to GitHub at the end of the blog.)

```shell
dotnet add package KeesTalksTech.Utilities.Rpc --version 0.3.2
```

## Remote Timer Example

I'll show you how things work using an example. Let's create a remotely controlled timer. Commands on the timer are actions like *start* and *stop*.

```cs
/// <summary>
/// Indicates the object implements a timer.
/// </summary>
public interface IRemoteTimer
{
    /// <summary>
    /// Gets a value indicating whether this instance is running.
    /// </summary>
    /// <value>
    /// <c>true</c> if this instance is running; otherwise, <c>false</c>.
    /// </value>
    bool IsRunning
    {
        get;
    }

    /// <summary>
    /// Gets the ticks total.
    /// </summary>
    /// <returns>The ticks.</returns>
    int GetTicksTotal();

    /// <summary>
    /// Sets the interval.
    /// </summary>
    /// <param name = "newInterval">The new interval.</param>
    void SetInterval(double newInterval);

    /// <summary>
    /// Starts this instance.
    /// </summary>
    void Start();

    /// <summary>
    /// Stops this instance.
    /// </summary>
    void Stop();
}
```

Let's implement the class:

```cs
using System;
using System.Timers;

public class RemoteTimer : IRemoteTimer, IDisposable
{
    private Timer timer;
    private int ticks = 0;

    /// <summary>
    /// Gets the interval.
    /// </summary>
    /// <value>
    /// The interval.
    /// </value>
    public double Interval
    {
        get;
        private set;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref = "RemoteTimer"/> class.
    /// </summary>
    /// <param name = "interval">The interval.</param>
    public RemoteTimer(double interval)
    {
        SetInterval(interval);
    }

    /// <summary>
    /// Sets the interval.
    /// </summary>
    /// <param name = "interval">The interval.</param>
    public void SetInterval(double interval)
    {
        var isRunning = (timer?.Enabled).GetValueOrDefault();
        timer?.Stop();
        timer?.Dispose();
        timer = new Timer(interval);
        timer.Elapsed += (s, e) => ticks++;
        Interval = interval;
        if (isRunning)
        {
            Start();
        }
    }

    /// <summary>
    /// Starts this instance.
    /// </summary>
    public void Start()
    {
        timer.Start();
    }

    /// <summary>
    /// Stops this instance.
    /// </summary>
    public void Stop()
    {
        timer.Stop();
    }

    /// <summary>
    /// Gets a value indicating whether this instance is running.
    /// </summary>
    /// <value>
    /// <c>true</c> if this instance is running; otherwise, <c>false</c>.
    /// </value>
    public bool IsRunning
    {
        get
        {
            return timer.Enabled;
        }
    }

    /// <summary>
    /// Gets the ticks total.
    /// </summary>
    /// <returns>
    /// The ticks.
    /// </returns>
    public int GetTicksTotal()
    {
        return ticks;
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        timer.Dispose();
    }
}
```

## Safety first

Classes have many (inherited) methods. There are some methods you most likely never ever want to expose (like the `Dispose` method). That's why the `Interpertation` is always done on an interface. This is especially important when you are using this project as part of RPC construction.

To execute JSON commands we'll need to create an `IInterpreter` based on an instance of the timer and the `IRemoteTimer` interface:

```cs
var json = "";
var timer = new RemoteTimer(10);
var interpretor = Interpretation.Create<IRemoteTimer>(timer);
```

## Executing a method

A method is defined as a JSON object with a `method-name` property. The system uses it to map it to a method.

```cs
/* Start the timer and assert it is running */
json = @"{ ""method-name"": ""Start"" }";
interpretor.Execute(json);

Assert.IsTrue(timer.IsRunning);
```

## Got parameters?

Parameters are defined as properties as well. Just add their names and values to JSON:

```cs
/* Set a new interval: */
json = @"{ ""method-name"": ""SetInterval"", ""newInterval"": 20 }";

interpretor.Execute(json);
Assert.AreEqual(20, timer.Interval);
```

## A series of methods

If you want to execute more than one method, just add the command in an array:

```cs
/* Stop the timer, set a new interval and restart it: */
json = @"[{ ""method-name"": ""Stop""},
          { ""method-name"": ""SetInterval"", ""newInterval"": 20 },
          { ""method-name"": ""Start""}]";

interpretor.Execute(json);
Assert.AreEqual(20, timer.Interval);
```

## How about retrieving information?

Thought of that as well! Any results are returned as an object or an array of objects (in case of a series):

```cs
/* Get tick information from timer */
json = @"{ ""method-name"": ""GetTicksTotal""}";
var ticks = interpretor.Execute(json);

Assert.IsNotNull(ticks);
Assert.IsInstanceOfType(ticks, typeof(int));
Assert.IsTrue(Convert.ToInt32(ticks) > 0);
```

## How about extension methods?

Extension methods are awesome. Let's define a `Pause` method:

```cs
public static class IRemoteTimerExtensions
{
    /// <summary>
    /// Pauses the specified timer.
    /// </summary>
    /// <param name = "timer">The timer.</param>
    public static void Pause(this IRemoteTimer timer)
    {
        if (timer.IsRunning)
        {
            timer.Stop();
        }
        else
        {
            timer.Start();
        }
    }
}
```

To allow extensions methods to be considered, they'll need to be given to the `Create`:

```cs
/* Pause the timer twice and assert running state */

var json = "";
var timer = new RemoteTimer(10);
var interpretor = Interpretation.Create<IRemoteTimer>(
    timer, 
    typeof(IRemoteTimerExtensions)
);

timer.Start(); 

json = @"{ ""method-name"": ""Pause"" }";
interpretor.Execute(json);
Assert.IsFalse(timer.IsRunning);

json = @"{ ""method-name"": ""Pause"" }";
interpretor.Execute(json);
Assert.IsTrue(timer.IsRunning);
```

## Wrap up

The code has potential to solve a host of problems. If you like to fork it, [please check GitHub](https://github.com/KeesCBakker/KeesTalksTech-Utility-Pack/tree/master/KeesTalksTech-Utility-Pack/KeesTalksTech.Utilities.Rpc) and let me know what you think. [The code used in the example can be found here](https://github.com/KeesCBakker/KeesTalksTech-Utility-Pack/blob/master/KeesTalksTech-Utility-Pack/KeesTalksTech.Utilities.Tests/Rpc/Examples/RemoteTimerExampleTest.cs).
