Mobile Backend as a Service gives web and mobile app developers access to cloud-based data storage through a simple API for data storage, push notifications, and security operations. I've previously covered how to integrate with Telerik Platform to manage security. In this article, I will walk through connecting to and working with data within a compiled .NET application.
The first step is to configure a project.
Download a copy of the Telerik Platform SDK for .NET and grab your API key and AppId for the a new data project that you want to work with. API keys are accessed from the menu on the left side of the screen:
The AppId for your data project can be found in the URL for the APIKey:
https://platform.telerik.com/#workspace/SOME-GUID/backendservices/YOUR APP ID/nav/BLAH-BLAH-BLAH
I like to save these values into AppSettings
, and be able to swap out those values with the IDs for a "production space" when I deploy my project to a production environment:
<appSettings>
<add key="Everlive.ApiKey" value="MY API KEY" />
<add key="Everlive.AppId" value="ANOTHER GUID HERE" />
</appSettings>
The BaseRepository
class that configures the settings and connection information. The BaseRepository looks like this:
public abstract class BaseRepository<T> : IRepository<T> where T : DataItem
{
private static readonly string _EverliveKey;
protected static readonly Guid _AppId;
static BaseRepository()
{
_EverliveKey = ConfigurationManager.AppSettings["Everlive.ApiKey"];
_AppId = Guid.Parse(ConfigurationManager.AppSettings["Everlive.AppId"]);
}
public BaseRepository()
{
var settings = new EverliveAppSettings()
{
ApiKey = _EverliveKey,
OutboundDateTimeProcessing = DateTimeValuesProcessing.ConvertToUtc
};
this._Everlive = new EverliveApp(settings);
}
private readonly EverliveApp _Everlive;
protected EverliveApp Everlive { get { return _Everlive; } }
protected SecuredDataHandler<T> GetDataSource()
{
return _Everlive.WorkWith().Data<T>();
}
}
What makes this BaseRepository
interesting is the generic parameter. In this way, you can wrap each of the Types in your Data project with a repository and be able to manage data appropriately within each type. If you have cross-cutting types, you can write more sophisticated methods into a concrete Repository
class that inherits from the BaseRepository
and does those extra tasks.
In the static constructor, the class will configure itself based on the content of the configuration file. In the instance constructor, a new connection to the Data project is established and made available to inheriting classes through the Everlive
property.
What is Everlive? That was the codename for the Data project that is now part of the Telerik Platform.
Add a method called GetDataSource
to request and provide a Type proxy for the Data project to the caller.
Now you have a connection to your data service. How do you start working with it?
When you work with a repository pattern, you want at least four methods: Get
, Add
, Update
and Delete
. In your BaseRepository
, you can simply define all of these methods with a line or two to navigate the Type proxy:
public T GetById(Guid id)
{
return GetDataSource().GetById(id).ExecuteSync();
}
public IEnumerable<T> GetAll()
{
return GetDataSource().Get().ExecuteSync();
}
public Guid Add(T newItem)
{
var result = GetDataSource().Create(newItem).ExecuteSync();
return result.Id;
}
public void Update(T itemToSave)
{
GetDataSource().Update(itemToSave).ExecuteSync();
}
public void Delete(Guid id)
{
GetDataSource().Delete(id).ExecuteSync();
}
Those should all look very self-explanatory. Get the data source, and operate appropriately for each method. Notice how they all end with ExecuteSync
? That is instructing the execution of the application to wait until a response is received from the Telerik Platform before proceeding. That could be a frustrating user experience, and it would be really cool if we could return a Task
object using the fancy new .NET 4.5 async pattern.
We can operate asynchronously using a Get
method to apply filters and return asynchronously:
public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> where)
{
return await GetDataSource().Get().Where(where).ExecuteAsync();
}
There are lots of big method signatures going on there, let's break it down:
T
object type.async
keyword, this method can be await
-ed, allowing other processes to proceed like repainting a user-interface while communication with the Telerik Platform is pending.where
is submitted to this method, allowing the processing and formatting of that condition to be managed by the .NET runtime. Depending on its contents, it can be translated and executed on the Telerik Platform server, thus reducing data in the transmission to our application.where
file asynchronously using the ExecuteAsync()
method call.That's an interesting implementation that will allow you to do filtering and reporting easily on the Telerik Platform.
Now that you have a base repository, how do you make the connection to real data types in .NET? In the sample Friends app, there is a Comments
type that has the following structure:
Define a C# class by inheriting from the Telerik.Everlive.Sdk.Core.Model.Base.DataItem
type and implementing properties with an OnPropertyChanged
method call in the setter. Below is the start of a Comments
class in C#:
[ServerType("Comments"), DataContract]
public class Comment : DataItem
{
private string _Comment;
[DataMember]
public string Comment
{
get { return _Comment; }
set
{
OnPropertyChanged(() => this.Comment);
_Comment = value;
}
}
}
The ServerTypeAttribute
specifies the data type that this class corresponds to. Built in to the SDK is an algorithm to match a C# class name to a type on the server. I prefer to hard-code these values to better assist in documenting the connection for the next developer to read my code.
The DataContractAttribute
tells the .NET runtime that this object will be transmitted in a service and to provide appropriate serialization for transport. The Comment
property is a simple wrapper property with a notification method call in the setter. This allows the DataItem
to be able to track changes and only transmit appropriate updates when the Update method is called. The DataMember
attribute is a marker to the serializer to tell it which properties should be transported.
With all of this code constructed, the actual repository for the Comment
types is laughably small:
public class CommentRepository : BaseRepository<Comment> { }
Yea, it's that simple. You can then get comments from the repository with commands like:
var repo = new CommentRepository();
var comments = repo.Get(_ => true);
Getting started working with the data in Telerik Data projects on the platform is easy. By providing .NET SDK access, you can create dashboards and other workflows that consume and work with data collected from mobile devices and websites using the JavaScript APIs. Telerik is giving you the options and choices to use whatever language or screen you want to interact with your data.
Jeffrey T. Fritz is a Microsoft MVP in ASP.Net and an ASPInsider with more than a decade of experience writing and delivering large scale multi-tenant web applications. After building applications with ASP, ASP.NET and now ASP.NET MVC, he is crazy about building web sites for all sizes on any device. You can read more from Jeffrey on his personal blog or on Twitter at @csharpfritz.