Show / Hide Table of Contents

Data Contracts

The concept of Glue technology is very similar to other service-oriented frameworks in terms of data passing. Glue is the message oriented framework where you exchange messages between contract-implementing/consuming endpoints. The types that you can pass from client to server and back are not limited to elementary .NET types. Any custom type can be transferred between client and server via Slim serialization.

Below is step-by-step guide to create NFX.Glue test server application that demonstrates non-elementary types transfer. The guide is quite brief in some places. For details, please check the demo.

1. Create new blank C# solution and add Class Library project DemoContracts with the reference to NFX (e.g. via NuGet)

2. Add the following types:

public enum Country
{
 Unknown,
 Argentina,
 England,
 Russia,
 USA
}

public class Location
{
  public Country Country { get; set; }
  public string City { get; set; }
}

public class Person
{
  public string Name { get; set; }
  public DateTime DOB { get; set; }
  public Country Citizenship { get; set; }
  public List<Location> Locations { get; set; }
}

3. Add IPersonService.cs file with the following contents:

[Glued]
[LifeCycle(ServerInstanceMode.Singleton)]
public interface IPersonService
{
  void Set(Person person);

  Person FindByName(string pattern); 
}

Notice the service is declared as singleton.

4. Add new C# Console Application project DemoServer with the references to NFX and DemoContracts project. Add DemoServer.laconf laconic configuration file:

application
{
  glue
  {
    bindings
    {
      binding
      {
        name="sync"
        type="NFX.Glue.Native.SyncBinding, NFX"
      }
    }

    servers
    {
      server
      {
        node="sync://localhost:8080"
        contract-servers=$"DemoServer.PersonService, DemoServer"
      }
    }
  }
}

Be sure to set Build Action : None and Copy to Output Directory: Always in the config file properties.

5. Add PersonService.cs file with the contents:

public class PersonService : IPersonService
{
  private List<Person> m_Persons;

  public PersonService()
  {
    m_Persons = new List<Person>();
  }

  public Person FindByName(string name)
  {
    lock(m_Persons)
      return m_Persons.Where(p => p.Name.Equals(name)).FirstOrDefault();
  }

  public void Set(Person person)
  {
    if (person == null) return;
    lock(m_Persons)
      m_Persons.Add(person);
  }
}

This class is singleton by contract and it maintains global state: m_Persons.

6. Add the following code to the Main method of DemoServer.Program.cs file

using (var application = new ServiceBaseApplication(args, null))
{
  Console.WriteLine("server is running...");
  Console.WriteLine("Glue servers:");
  foreach (var service in App.Glue.Servers)
    Console.WriteLine("   " + service);

  Console.ReadLine();
}

7. Add the last one C# Console Application project DemoClient with the references to NFX and DemoContracts project. Add DemoClient.laconf laconic configuration file:

application
{
  glue
  {
    bindings
    {
      binding
      {
        name="sync"
        type="NFX.Glue.Native.SyncBinding, NFX"
      }
    }
  }
}

Again, be sure to set Build Action : None and Copy to Output Directory: Always in the file properties.

8. Create client proxy class that will operate with the service above:

gluec "$(SolutionDir)DemoContracts/bin/Debug/DemoContracts.dll" /o out="$(SolutionDir)DemoClient" cl-suffix="AutoClient"

Rebuild DemoContracts project and add the file PersonServiceAutoClient.cs to the DemoClient project (the file will appear in the root of the project).

9. Add the following code to the Main method of DemoClient.Program.cs:

using (var application = new ServiceBaseApplication(args, null))
{
  using (var client = new PersonServiceAutoClient("sync://localhost:8080"))
  {
    while (true)
    {
      var input = Console.ReadLine();
      var cmd = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
      exeCommand(client, cmd);
    }
  }
}

Add the following method:

private static void exeCommand(PersonServiceAutoClient client, string[] cmd)
{
  if (cmd[0].Equals("add"))
  {
    var person = new Person
    {
      Name = cmd[1],
      DOB = DateTime.Now.AddYears(-cmd[2].AsInt()),
      Citizenship = Country.Argentina,
      Locations = new List<Location> { new Location { Country = Country.USA, City = "NY" } }
    };

    client.Set(person);
    return;
  }

  if (cmd[0].Equals("find"))
  {
    var name = cmd[1];
    var result = client.FindByName(name);
    if (result == null)
      Console.WriteLine("Not found");
    else
      Console.WriteLine("Name: {0}, Age: {1}, Citizenship: {2}, Locations: {3}",
                        result.Name,
                        (int)(DateTime.Now - result.DOB).TotalDays / 366,
                        result.Citizenship,
                        result.Locations.Count());

    return;
  }
}

You will also need to add usings

using NFX;
using NFX.ApplicationModel;
using DemoContracts.GluedClients;

10. Run DemoServer server host and start the DemoClient client application. Execute the following commands sequentially: "add John 12", "add Anna 23", "find John", "find Ivan". The output will be

Name: John, Age: 20, Citizenship: Argentina, Locations: 1
Name: Anna, Age: 23, Citizenship: Argentina, Locations: 1
Not found
Back to top Copyright © 2006-2018 Agnicore Inc
Generated by DocFX