This next post in the series aims to explore a common approach for using NoSQL across different cloud implementations seamlessly from your cloud agnostic application. At the end of this article you will be performing data operations to all three clouds using C# on the .Net core platform.

The technologies to be used will be:

DynamoDb on AWS

DataStore on Google Cloud

CosmosDB using MongoDB on Azure

Before we jump in let’s go through what you will need to get started:

If you are yet to create an account for these services go ahead and do this as it only takes a couple of minutes and should be cost free as long as you clean up resources once you are finished.

And what we will cover:

Give me the code!

If you want to follow along or just get going with the samples the completed code can be found over on Github:

A skeleton solution is provided which will give you everything up to the end of this part.

A complete solution is provided which will give you all the cloud implementations up to the end of the complete article.

1 Interface for the NoSQL operations

The demo to be constructed will be based around the following contracts.

IDataStore contains all DataStore operations that we will be performing against the respective cloud providers.

public interface IDataStore<T> { Task AddEntity(T item); Task UpdateEntity(T item); Task DeleteEntity(T item); Task GetEntity(T item); Task QueryEntity(ICriteria criteria); }

ICriteria contains basic properties to support queries against the respective cloud providers.

public interface ICriteria { Dictionary SearchFields { get; set; } int PageSize { get; set; } string NextPageState { get; set; } }

2 Solution setup, test harness and plumbing

At the end of this section will have the:

Solution and Project structure for each implementation

.Net core test harness

Configuration of cloud accounts

Basic console logging so we know what’s going on

This early separation of all the logical components makes it easy to manage dependencies and keep things simple as the project grows with each implementation.

2.1 Solution Setup

For this demo create a solution called CloudNoSQL and add a .Net Standard project named NoSQL.Behaviours that will contain two interfaces; IDataStore and ICriteria copying the respective contents:

Next add the following .net standard projects for each storage implementation.

DynamoDB

DataStore

CosmosDB

Add a project called CommonTypes and create the folders

Settings

Behaviours

Messages

In the Behaviours folder create an interface called IAppLogger and add the operations below:

public interface IAppLogger { void LogError(Exception ex); void LogWarning(string message); void LogMessage(string message); }

In the Settings folder create the following three class files

AWSSettings

AzureSettings

GCPSettings

Finally in the messages folder create a class called GameState which will contain some state from a fictitious game that we wish to save to our NoSQL Datastore. Based on the type from the Queueing sample we have added a few extra parameters to support the datastore operations across providers.

public class GameState { public string RecordId { get; set; } public string PlayerId { get; set; } public int Health { get; set; } public int CurrentLevel { get; set; } public Dictionary Inventory { get; set; } public string GameId { get; set; } public DateTime RecordCreatedAt { get; set; } public string PlatformKey { get; set; } public string PlatformType { get; set; } }

For each of the implementation projects add the following classes

AWSGameStateStore

GCPGameStateStore

AzureGameStateStore

Next make sure each of the classes inherit from and implements the IDataStore interface. When you are done you solution should resemble:

2.2 Prepare Constructors

Next we will update the constructors of the data stores to accept a settings type and the IAppLogger interface that we created earlier. Make the changes listed below to the respective files

AWSGameStateStore, GCPGameStateStore and AzureGameStateStore

AWSGameStateStore:

private AWSSettings _awsSettings; private IAppLogger _appLogger; public AWSGameStateStore(IAppLogger appLogger, AWSSettings awsSettings) { _awsSettings = awsSettings; _appLogger = appLogger; }

GCPGameStateStore:

private GCPSettings _gcpSettings; private IAppLogger _appLogger; public GCPGameStateStore(IAppLogger appLogger, GCPSettings gcpSettings) { _gcpSettings = gcpSettings; _appLogger = appLogger; }

AzureGameStateStore:

private AzureSettings _azureSettings; private IAppLogger _appLogger; public AzureGameStateStore(IAppLogger appLogger, AzureSettings azureSettings) { _azureSettings = azureSettings; _appLogger = appLogger; }

2.3 TestHarness setup

Our test harness will be a simple console application that can be run locally with configuration sourced from a local appSetting.json file.

To get started add a .Net Core Console Application to the solution and name it TestHarness.

Next add a settings.json file and paste in the following skeleton json:

{ "aws": { }, "azure": { }, "gcp": { } }

These will be empty for now but the placeholders will be updated as we progress.

Next add a class called ConsoleLogger and paste in the code from the following gist:

This basic logger will output basic instrumentation to the console so we can monitor activity.

Next we need to add in some support for the appSettings.json file as we will be loading settings from this file in later sections.

In the “Manage Nuget Packages” find and add the following packages to the TestHarness project:

Extensions.Configuration (v2.0.0 at time of writing)

Extensions.Configuration.Binder (v2.0.0 at time of writing)

Extensions.Configuration.FileExtensions (v2.0.0 at time of writing)

Extensions.Configuration.Json(v2.0.0 at time of writing)

When you are finished your installed packages should look like this.

Your project solution should now look something like this:

Next we need to update Program.cs with some code to load our [empty] config from the appSettings.json file, and check that our logger is alive.

Copy the code from the following gist into Program.cs

Resolve any references that may be required and Hit F5, and you should see the following:

And that’s it all our plumbing is complete time for the fun stuff!

If you want the code for this skeleton app you can get it from GitHub here:

In part two we will get started with the AWS Implementation.

If you have any queries / problems / feedback with this part please comment below.