Replacing WCF with AspNetCore Rest API as transport layer for XPO

Replacing WCF with AspNetCore Rest API as transport layer for XPO

I have been using XPO from DevExpress since day one. For me is the best O.R.M in the dot net world, so when I got the news that XPO was going to be free of charge I was really happy because that means I can use it in every project without adding cost for my customers.

Nowadays all my customer needs some type of mobile development, so I have decided to master the combination of XPO and Xamarin

Now there is a problem when using XPO and Xamarin and that is the network topology, database connections are no designed for WAN networks.

Let’s take MS SQL server as an example, here are the supported communication protocols

  • TCP/IP.
  • Named Pipes

To quote what Microsoft web site said about using the protocols above in a WAN network

https://docs.microsoft.com/en-us/sql/tools/configuration-manager/choosing-a-network-protocol?view=sql-server-2014

Named Pipes vs. TCP/IP Sockets

In a fast-local area network (LAN) environment, Transmission Control Protocol/Internet Protocol (TCP/IP) Sockets and Named Pipes clients are comparable with regard to performance. However, the performance difference between the TCP/IP Sockets and Named Pipes clients becomes apparent with slower networks, such as across wide area networks (WANs) or dial-up networks. This is because of the different ways the interprocess communication (IPC) mechanisms communicate between peers.”

So, what other options do we have? Well if you are using the full DotNet framework you can use WCF.

So, it looks like WCF is the solution here since is mature and robust communication framework but there is a problem, the implementation of WCF for mono touch (Xamarin iOS) and mono droid (Xamarin Android)

You can read about Xamarin limitations in the following links

Android: https://docs.microsoft.com/en-us/xamarin/android/internals/limitations

iOS: https://docs.microsoft.com/en-us/xamarin/ios/internals/limitations

I don’t want to go into details about how the limitation of each platform affects XPO and WCF but basically the main limitation is the ability to use reflection and emit new code which is needed to generate the WCF client, also in WCF there are problems in the serialization behaviors.

Well now that we know the problem is time to talk about the solution. As you know XPO has a layered architecture ( you can read about that here https://www.jocheojeda.com/2018/10/01/xpo-post-5-layered-architecture/)

So basically, what we need to do is to replace the WCF layer with some other technology to communicate to the database server

The technology I’ve selected for this AspNetCore which I would say is a really nice technology that is modern, multi-platform and easy to use. Here below you can see what is the architecture of the solution

AspNetCore

Rest API

So, what we need basically is to be able to communicate the data layer with the data store through a network architecture.

The network architecture that I have chosen is a rest API which is one of the strong fronts of AspNetCore. The rest API will work as the server that forward the communication from XPO to the Database and vice versa, you can find a project template of the server implementation here https://www.jocheojeda.com/download/560/ this implementation references one nuget where I have written the communication code, you can fine the nuget here https://nuget.bitframeworks.com/feeds/main/BIT.Xpo.AgnosticDataStore.Server/19.1.5.1

Also we need a client that is able to interpret the information from the rest API and feed XPO, for that I have created a special client you can find here https://nuget.bitframeworks.com/feeds/main/BIT.Xpo.AgnosticDataStore.Client/19.1.5.1

The client implementation has been tested in the following platforms

  • Xamarin Android
  • Xamarin iOS
  • Xamarin WPF
  • DotNetCore
  • DotNetFramework

The client implementation has been tested in the following operative systems

  • Android 5 to 9
  • iOS 9 to 11
  • MacOS: Sierra to Catalina
  • Windows 10

In this link, you can see a full implementation of the server and the clients (XAF and Xamarin)

What is next? Well here are a few topics for the upcoming posts

  • Understanding JWT tokens
  • How to secure your data store service with a JWT token
  • Hosting multiple data store with a single service
  • Implementing your own authentication method
  • Examples examples examples

 

Exposing your XPO ORM using GraphQL dotnet

Exposing your XPO ORM using GraphQL dotnet

Exposing your XPO ORM using GraphQL

Note: you can download the full source code for this article in my GitHub repository 

In the past few years, I have been working on developing mobile applications, in the mobile world most of the applications will consume some type of data service, the main problem here is how to choose the correct data service? There are a lot of technologies to expose data over the wire and all of them are good somehow, so for me, the quest is about to find a technology where can I use my current skill set.

Today subject of study is GraphQL, an open source technology developed by Facebook that is a data query and manipulation language for API.

The beauty of GraphQL is its efficient and flexible approach to develop web APIs that can be queried to return a different data structure in the opposite side of the REST API and traditional web services that return a fix data structure, you can learn more about the GrahpQL project on their website https://graphql.org/

First, we will start by creating a new Asp.net core web application

A screenshot of a cell phone Description automatically generated

We name the application

A screenshot of a cell phone Description automatically generated

Then we select Empty for the project type

A screenshot of a cell phone Description automatically generated

Now that the project is created, we need to add a few NuGet packages, you can copy and paste the following snippet inside of your csproj file

<ItemGroup>

<PackageReference Include="DevExpress.Xpo" Version="18.2.7" />

<PackageReference Include="GraphQL" Version="2.4.0" />

<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="3.4.0" />

<PackageReference Include="GraphQL.Server.Transports.WebSockets" Version="3.4.0" />

<PackageReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />

<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" />

<PackageReference Include="System.Reactive" Version="4.1.5" />

</ItemGroup>

 

Now if let’s try to compile and run the application, at this moment you should see a “hello world” in your browser

A screenshot of a cell phone Description automatically generated

Now let’s add a second project to the solution to host the ORM, for that let’s use a NetStandard class library

A screenshot of a cell phone Description automatically generated

Let’s name the project XpoOrm, then edit the project file and add the following NuGet packages

<ItemGroup>

<PackageReference Include="DevExpress.Xpo" Version="18.2.7" />

<PackageReference Include="GraphQL" Version="2.4.0" />

<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="3.4.0" />

<PackageReference Include="GraphQL.Server.Transports.WebSockets" Version="3.4.0" />

<PackageReference Include="System.Reactive" Version="4.1.5" />

</ItemGroup>

 

Now let’s add 3 folders, schema, services and models

A close up of a logo Description automatically generated

The basic structure of our project is ready, so let’s start adding some models, we will add 2 models products and categories, you can get the source of the files here

A screenshot of a cell phone Description automatically generated

A screenshot of a cell phone Description automatically generated

When you finish implementing the models the next step is to implement the services, remember that the main goal of GraphQL is to create a queryable layer between the client and the data service, you can architecture your service in the way that is more convenient for you but in this case I will create one service per entity, this services will be injected in our application using asp.net dependency injection. You can find the source for the services here

Product Service

A screenshot of a cell phone Description automatically generated

Category Service

A screenshot of a cell phone Description automatically generated

So far there we have not written any code related to GraphQL so now it’s the time. GraphQL does not directly expose your data model class instead it builds a type based on your model, let’s see how this will work for the Category model

A screenshot of a cell phone Description automatically generated

As you can see, I have created a new class that inherits from ObjectGraphType<T> where T is our XPO persistent class. Also, in the constructor I used the fluent API to map the fields from the category model to the CategoryType class, the method Field contains several overloads so you can do any type of crazy stuff in here, but for now I’m going keep it simple, now lets create the type for the product model.

A screenshot of a cell phone Description automatically generated

Now that we have created the ProductType class we can see that there are new characteristics here, the first new thing that you will notice is that in the constructor I injected the category service to load the category object related to the product, that is the common design pattern of GrahpQL, this approach is  useful if you are using POCO objects. Also, if you see the commented-out code you can see that when we use XPO we don’t need to inject the category service since it can be loaded directly from the instance of the Product class using XPO lazy loading feature. You can find both graph types here

Now that we have our graph types, we need to create 2 more classes, an object that will hold our list of queries and a schema object that will provide information about the types and the queries that we are exposing, let’s start with the queries object

A screenshot of a cell phone Description automatically generated

The Queries object is basically another graph type, but instead of exposing a model class is exposing the object class, it also uses the dependency injection to inject the 2 services that will forward the data to the fields. Now its time to create the schema for our GraphQL service

A screenshot of a cell phone Description automatically generated

A GraphQL schema can only expose one query so that is why I have created the object queries to hold all the possible subqueries of our services. As you can see, I injected the queries object and the dependency resolver, you can find the code for these classes here.

Now its time to go back to the asp.net core service and start the configuration of GrahpQL, let’s start with the program class

A screenshot of a cell phone Description automatically generated

As you can see in the main method there is some boilerplate code to initialize XPO data layer and create some sample data, nothing new if you are an XPO user you might be already familiar with this code. Now let’s move to the startup class

A screenshot of a cell phone Description automatically generated

As any asp.net core web application, there are 2 important methods let’s see what happened on each of them.

In the configure services method I register the services I created and the graph types also added the GraphQL service and the web sockets and data loader.

Now in the configure method I enabled the use of default files and static files, web sockets also I exposed the GrahpQL schema using web sockets and GrahpQL (this is the HTTP version of the API)

Our API is almost done, there is only one last step we need to do, we need a way to test our API for that we will use Graphical which is a web client to query GrahpQL APIs, the graphical project is hosted here https://github.com/graphql/graphiql but to make it simpler you can download the files from my GitHub repository here

Let’s create a wwwroot folder and add the graphical files into it

Run the application, you should see the graphical U.I and you should be able to navigate the API documentation

A screenshot of a social media post Description automatically generated

or you can query of XPO ORM

A screenshot of a social media post Description automatically generated

As you can see there is autocomplete on the query editor also we are able to query objects and nested objects on a field-based manner

This article is the first article on a series of how to expose any XPO ORM using GraphQL, in the next post we will learn about mutations

XPO and database replication

After 15 years of working with XPO, I have seen many tickets asking if XPO is capable of doing data replication and all the time DevExpress team answer those tickets saying that replication its out of the scope of XPO and that it’s actually true.

So, to start talking about database replication lets try to define what “replication” means. Here is the definition of replication according to Wikipedia

“A computational task is typically replicated in space, i.e. executed on separate devices, or it could be replicated in time, if it is executed repeatedly on a single device. Replication in space or in time is often linked to scheduling algorithms”

The keywords on the above statement are task, space and time, so to replicate a database operation we need to know the following information

  • What was the task?
  • Who performed the task?
  • When was the task performed?
  • Who needs to know about the task what was performed?

Now let’s think what are the steps that any traditional database does, in order to replicate the data between instances

  • It shares a copy of the database schema to the other instances/locations/devices
  • It logs the DML statements that happened to a main instance/location/device
  • It broadcast the statements on this log to the other instances/locations/devices
  • it processes the statements on the target instance/locations/devices

Now the question is, can we do the same with XPO?

thanks to the great architecture develop by the XPO Team, the answer is a big YES!!!

so, let’s compare how you can match traditional database replication with XPO

Traditional database replication XPO database replication
1 Share a copy of the database schema. In XPO we can re-create a database schema using the method UpdateSchema from the Session class.
2 Logs the DML statements. In XPO we can keep track of the BaseStatement at the DataLayer level.
3 Broadcast the statements

 

 

We can transport the log of statements using any of the dot net network technologies like WCF, remoting or Web API.
4 Process the statements on the target instance, device or location

 

 

To process any kind of BaseStatement we can use the XPO DataLayer on the target instance, device or location

 

So, it looks like DotNet and XPO provide us of all the necessary infrastructure to do a database replication so why not give it a try right?

XPO POST 5: Layered Architecture

There is nothing than inspire me more to write a blog post that a regular Saint Petersburg day and by regular, I mean windy, cold, dark and rainy, but don’t get me wrong I love this city but when the weather is too nice as it was this past summer is hard to focus on writing.

So, let’s get started with the post number 5, today we are going to talk about the architecture of XPO.

If you are new to XPO you might find that the documentation is sometimes overwhelming especially because most of the articles blogs and tickets are written in totally different times and versions of XPO, so you might find some really old blog post where the WCF scenario is not supported and the XpoProviders are tightly coupled with the DotNet ADO Providers and some other cases where is the opposite case.

XPO is now 15 years old and its architecture has changed since the early versions, most of the time when you find documentation about XPO layer architecture you won’t be able to see all the layers at once.

After spending 1 month and Gilbert Arizona, developing software side by side with my dear friend and student Jose Javier Columbie and having endless technical conversations about XPO, I realize that it is not easy to explain how the XPO architecture works, so I decided to draw the XPO architecture in a formal document. Javier also drew the first version of this diagram on his notepad and as always half in Spanish and half in English as we tend to do as Latin Americans.

So, without further due, here I present you the XPO architecture diagram

If you want to get a copy of the diagram with clickable links, you can download it here [download id=”172″]

Now let’s start explaining from left to right.

Persistent Classes: this layer is basically defined by you as the programmer and is nothing more than the persistent classes you write to abstract business objects. Usually, this layer is your starting point as an XPO user, so I won’t go into deeper detail since if you are reading this post you already know how this layer works.

Data Access, Data Cache and Data Filtering: in this layer, the most basic object is the session also is the base class for all the other objects in this layer. A session is basically a cache of all the persistent objects that have been instantiated since you start manipulating your DataStore or the objects that you have queried in your DAL (Data Access Layer).

Most of the behaviours from the session are passed to its child classes, won’t explain the difference on the child classes in this article but for sure it will be on my list of topics for the following weeks.

Object Access Layer: this layer is the bridge between the session and the actual DataStore. So basically, it works as a translator for the CRUD operations done in an object-oriented manner to statement objects that will be processed in the data access layer level.

Data Access Layer: is the bridge between the object access layer and the data stores (classes that implements IDataStore) and its basically in charge of pass the statement objects to the data store so it can translate it to the proper SQL statements for a specific database like MS SQL Server, Postgres, Mysql, etc.

Data Store Layer: is the lowest layer of all and it’s in charge to translate the statement objects to DDL and DML SQL statements and execute them at the database level using ADO.

Also, as you can see in the diagram this layer can be transferred over the wire using WCF to extend the functionality on the communication with the database. Using WCF is really useful if you don’t want to expose the connection string on the application config or if you want to transport the communication to the database in any of WCF supported network protocols.

 

XPO POST 4: Connection Strings

When XPO was first released it supported MSSQL Server and MS Access as the main database systems, most of the examples and documentation did not specify how XPO connected to the database, at that time it looks like the connection to the database happened like magic.

There was little to none information about how to connect to a DBRMS that were not MSSQL Server or MS Access

So I decided to post a ticket to developer express asking how can I create the correct connection string for each of the supported database, and that is the origen of this ticket that I use on all my presentations lectures about XPO.

Here is a sample of each of the supported connection strings

AccessConnectionProvider: MSAccess                                                XpoProvider=MSAccess;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;
DataSetDataStore: XmlDataSet
XpoProvider=XmlDataSet;Data Source=C:\mydatabase.xml;Read Only=false
InMemoryDataStore: InMemoryDataStore
XpoProvider=InMemoryDataStore;Data Source=C:\mydatabase.xml;Read Only=false
MSSqlConnectionProvider: MSSqlServer
XpoProvider=MSSqlServer;Data Source=(local);User ID=username;Password=password;Initial Catalog=database;Persist Security Info=true
AdvantageConnectionProvider: Advantage
XpoProvider=Advantage;Data Source=\\myserver\myvolume\mypat\mydd.add;ServerType=local;User ID=ASSSYS;TrimTrailingSpaces=true
AsaConnectionProvider: Asa
XpoProvider=Asa;Uid=MyUsername;PWD=MyPassword;DBF=c:\mydatabase.db;Persist Security Info=true
AseConnectionPrvider: Ase
XpoProvider=Ase;Port=5000;Data Source=MyAseServer;User ID=MyUserName;Password=MyPassword;Initial Catalog=MyDatabase;Persist Security Info=true
DB2ConnectionProvider: DB2
XpoProvider=DB2;Server=MyAddress:MyPortNumber;User ID=MyUserName;Password=MyPassword;Database=MyDatabase;Persist Security Info=true
FirebirdConnectionProvider: Firebird
XpoProvider=Firebird;DataSource=localhost;User=SYSDBA;Password=masterkey;Database=MyDatabase.fdb;ServerType=0;Charset=NONE
MSSqlCEConnectionProvider: MSSqlServerCE
XpoProvider=MSSqlServerCE;Data Source=MyDatabase.sdf;Password=MyPassword
MySqlConnectionProvider: MySql
XpoProvider=MySql;Server=MyServerAddress;User ID=MyUserName;Password=MyPassword;Database=MyDatabase;Persist Security Info= true;Charset=utf8
ODPConnectionProvider: ODP
XpoProvider=ODP;Data Source=TORCL;User ID=MyUserName;Password=MyPassword
ODPManagedConnectionProvider: ODPManaged
XpoProvider=ODPManaged;Data Source=TORCL;User ID=MyUserName;Password=MyPassword
OracleConnectionProvider: Oracle
XpoProvider=Oracle;Data Source=TORCL;User ID=MyUserName;Password=MyPassword
PervasiveSqlConnectionProvider: Pervasive
XpoProvider=Pervasive;Server=MyServerAddress;UID=MyUserName;PWD=MyPassword;ServerDSN=MyDatabase
PostgreSqlConnectionProvider: Postgres
XpoProvider=Postgres;Server=127.0.0.1;User ID=MyUserName;Password=MyPassword;Database=MyDatabase;Encoding=UNICODE
SQLiteConnectionProvider: SQLite
XpoProvider=SQLite;Data Source=filename
VistaDBConnectionProvider: VistaDB
XpoProvider=VistaDB;Data Source=C:\mydatabase.vdb4
VistaDB5ConnectionProvider: VistaDB5
XpoProvider=VistaDB5;Data Source=C:\mydatabase.vdb5

By default, when you start using XPO without specifying a connection string it will connect by to MSAccess.

The XPO connection string is a special type of connection string, it is somehow the same as your regular .net connection string, but it includes the parameter “XpoProvider”, you can learn more about this on my post about the XpoProviders. The need of having the parameter XpoProvider is the connection string is because otherwise, it will be impossible to identify the database engine that you want to use with XPO as you can see on the following screenshot from DevExpress website.

There are 2 special cases that XPO can use a regular connection string

  1. When you are using an MSSQL Server as your RDBMS, you can just use a regular connection string without the need to specify an XpoProvider.
  2. When you are using MS Access with OleDb you can also use a just regular connection string

You can see a real-life example when you create an XAF application and you check the app or web config, here is a screenshot of the possible connection strings

Besides the connection string as literal strings, you can also ask the XpoProvider to generate the correct connection string for you on runtime using the static method of “GetConnectionString”. You can see an example of how to use PostgreSqlConnectionProvider to generate the correct connection string, in DevExpress official documentation here. The same goes for all of the XpoProviers, you can information about each provider in the documentation for the DevExpress.Xpo.DB namespace.