Part 16 - Understanding the Hub App Template’s Sample Data Model

Play Part 16 - Understanding the Hub App Template’s Sample Data Model
Sign in to queue

Description

In this lesson, we’ll pick back up with the default Hub App Template prior to making any changes to it.  Previously we learned about the Hub control and its Hub Sections, and how each panel of content in the Hub control is arranged using a series of data templates.  In this lesson, we’ll look at where the actual data is coming from.  In the next lesson, we’ll look at how we use the data model to bind the user interface to the underlying data.

First, at a high level, the idea of binding is that you have a collection of objects, for example, let’s say a collection of Cars like so:

List<Car> cars = new List<Car>();

Let’s suppose that the Car class is simple, like the classes we worked with in the C# Fundamentals for Absolute Beginners series.

    public class Car
    {
        public int Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }
        public string ImagePath { get; set; }
    }

You can add cars to that collection by retrieving data from a text file, a database, etc.  Suppose you read from a comma delimited file or a JSON (JavaScript Object Notation) file and create a new instance of the Car class for each row of data in that file.

At this point, you would have a complete (albeit, a very simple) data model.  In other words, the classes and the code that opens the data file, reads it, and turns it into instances of objects, and adds those objects to a collection, is essentially the data model.

And once you have that data model in place, essentially a collection of Cars in memory, you can bind that collection to a GridView or some other list-style control that will allow you to display them in a tabular or grid-like manner.  You could use the ImagePath as the data source for a thumbnail picture of the given car.  You could display the Make and Model in text that appears on top of the image.  Clicking a given item in the GridView would allow you to see more information about the given car in the ItemsDetail.xaml page.  More about that in the next lesson.

Hopefully you understand what we’re trying to achieve.  The Hub App Template supplies you with a generic data model including sample data, classes that represent data structures, and classes that provide access to the instances of those data structures.  Ideally you can just modify what they already have and use it for whatever type of data you want to work with.  In fact later in this series, we’ll do exactly that — we’ll modify the Hub App Template to create a complete app that displays images and recipes for cupcakes.

The data model created by the Hub App Template is self contained in the \DataModel folder.  There are two files:

SampleDataSource.cs - This single file has multiple parts, but it defines a class for sample data items, as well as a class that is used to group the items together.  This gives you a simple hierarchical structure you can wrap your mind around.  If you need to further add another grouping on top of that, you can extend this.  Furthermore, you can scrap this all together.  All you really need is a collection of objects, or some other object graph.  The SampleDataSource.cs also knows how to open a data file, retrieve the results, and create instances of the Item and Group objects.  So, unfortunately, this serves several purposes and as a result, the code may be a bit obscure for beginners.

Where does the actual data come from?

SampleData.json - JSON stands for JavaScript Object Notation.  I created a lesson in the JavaScript Fundamentals for Absolute Beginner’s series about JSON.  I recommend you watch that for a thorough explanation of the syntax.

Now, I get asked the following questions often:

(1) Why did the developers of this template choose the JSON format over, say, a comma delimited file format?

Well, I don’t have any special knowledge about this, but I suspect two reasons.  First, JSON files can easily represent object graphs, or rather, collections that contain objects (in this case, “Groups”) that have a property (”Items”) which is a collection of an object (”Item”).  You don’t get that structure from a flat comma-delimited file.  Secondly, it’s relatively easy to read and write JSON using built-in classes as we’ll learn throughout the remainder of this series.

I realize at first glance, JSON can be a bit intimidating.  However, the good news is that it is quickly becoming a very popular file format and has the added benefit of being easily utilized by JavaScript and some commercial and open source document databases.

(2) Can I use some sort of structured relational database instead of JSON?

I have not personally done this, but I know some have tried to use a SQL Server Compact or LocalDb.  Others have had success with a local file-based database called SQLite.  I’ve not tried either of these techniques but I suspect it is possible.  Also, you could use some external service such as those available on Windows Azure or Azure Mobile Services.  We don’t cover those in this series, but these are all options depending on the requirements of your application.

One final thing I want to address conceptually / generically: what is a “data model”?  This is a term that deals with your application’s architecture, or in other words, how you separate and layer your application’s code.  Typically you want to keep logical layers separated and in most applications that means you keep the persistence code separate from the business rules, or rather, the domain logic, and you keep all of that separate from the presentation logic that displays data to the user.  The benefit of abstracting the various responsibilities of your application into software  layers is that you can manage change more effectively.  I’ll resist the urge to talk about this in more detail.

The “data model” is a layer that encapsulates all of the logic required to retrieve data from an underlying data source, such as a JSON file or a database, and put it into an object graph that can be used by the other layers of the software.  In our case, the result of calling into the data model is an object graph that contains the data that we’ll display in our application.

As I said earlier, the data model — more specifically the SampleDataSource.cs — has several classes all collected into one file.

The SampleDataItem class is the child.  It is what you see in “SECTION 2” of the Hub. 

The SampleDataGroup class is the parent.  It has an Items property which is a collection of SampleDataItem.  (Actually, it is a special type of collection called an ObservableCollection<T> which we’ll talk about in another video.  For now, just think of it as a simple List<T> and I’ll explain the difference later.)

For the most part, SampleDataItem and SampleDataGroup are just data structures … no methods outside of the constructor, just a set of properties.

All of the real heavy lifting in regards to retrieving data and creating instances of the SampleDataItem and SampleDataGroup classes is in the SampleDataSource class. 

It looks like there’s a lot going on here, so let’s make sure we understand what it is doing.

First this line of code:

private static SampleDataSource _sampleDataSource = new SampleDataSource();

… is a coding pattern called “Singleton”.  It forces just one instance of the class to be created, never more.  That way you can always make sure you’re working with the same instance of the class.

Next:

        private ObservableCollection<SampleDataGroup> _groups = new ObservableCollection<SampleDataGroup>();
        public ObservableCollection<SampleDataGroup> Groups
        {
            get { return this._groups; }
        }

This exposes a Groups property which is a collection of SampleDataGroup.  Exposing this property makes it easy to bind to the Groups and Items using the binding syntax in XAML.  More about that in the next lesson.

The next three methods will return ALL groups, one specific group, or one specific item by either returning the _groups, or by performing some LINQ to Objects query on _groups:

public static async Task<IEnumerable<SampleDataGroup>> GetGroupsAsync() { … }

public static async Task<SampleDataGroup> GetGroupAsync(string uniqueId) { …}

public static async Task<SampleDataItem> GetItemAsync(string uniqueId) { … }

Notice that they each call the EnsureSampleDataLoaded() method:

private static async Task EnsureSampleDataLoaded()
{
  if (_sampleDataSource == null || _sampleDataSource.Groups.Count == 0)
    await _sampleDataSource.GetSampleDataAsync();

  return;
}

In other words, make sure we’ve loaded up the data before continuing.  If Groups is empty, go load that data! 

That leads us to the final method in the class, GetSampleDataAsync().  Before I talk about that …

I’ve taken a great liberty by ignoring keywords that embellish these methods like “async” and “Task<T>” and even the “await” keyword.  We’ll devote an entire lesson to a high level explanation of these ideas.  Let’s just ignore they exist for now.

In pseudo code, the GetSampleDataAsync() method does the following:

- Make sure there’s no data in Groups.  If there is, this isn’t necessary.
- Open the data file. 
- Read the file’s contents into a string, then parse it to JSON (or actually, into an array of JSON)
- Loop through the array, creating a Group object
- One element of the array contains another JSON array (Items). 
- Loop through that array, creating an Item object, add it to the Items collection.
- Add the group (and all of its children) to the Groups collection.

Now, when the GetGroupsAsync(), GroupGroupAsync(), GetItemAsync() or just the Groups property are accessed, we’ll have data available.

So, that’s how the *sample* Data Model works.  However I think it is important to emphasize that you don’t have to follow this exact technique / approach.  You can replace some or all of this.  It’s just a template, not a requirement.  Your application may require a less complex class hierarchy, or perhaps a more complex one.  You may replace the JSON file with some other data source.  You can even retrieve data from over the Internet like in the case with Windows Azure and Azure Mobile Services.  At the end of the day, you’ll want to make this yours.  As long as the result of your data model is collection you can bind to from within XAML, you’re in good shape.  That’s what we’ll talk about in the next two lessons.

Embed

Download

Download this episode

The Discussion

Add Your 2 Cents