Sara can has DataService – Part 6 – Writing a Xamarin.Forms app

Just joining my series? Check out my first blog post in this series for an overview on what I’m building.

To follow along, here’s the diff from last blog post.

What I learned

  • The term “service” is a naming convention. There’s no special library you have to install to make a class act as a “service”.
  • Not everything has to be instantiated. Yeah this is the first time I’ve been forced to think this way. You don’t have one of your view models or your main app class instantiate your service. Use either a singleton or a static class.
  • Global variables are not good form. I can’t stop my brain from wanting to do a List somewhere off of the main App as the source of truth. Let the data service handle this. It will make more sense in this blog post and the next post.

Creating a FabricsDataService

First, create a new folder called Services and add a blank C# class there called FabricsDataService

Back in the days where I was a developer (SDET) on the VS team (LONG time ago), I remember the advice I got from a developer reviewing my code. He said, “Think about writing your Object Model from the point of view of the caller. Start by writing your test cases, thinking about what methods you wish were already available, and then go implement those methods.” This conversation might have been my first introduction to HCI / UX. 

Writing a service is kinda like writing that object model ages ago. Start with what methods you wish were available to you, and then go implement them. For example, in PageOneViewModel.cs in the constructor, I’m creating fabric objects just to populate the ObservableCollection.

In GitHub, press y to get a permalink to a specific commit; otherwise, if you use master and it gets updated, your link might not make sense moving forward.

For example, I’m doing

        public PageOneViewModel(INavigation Navigation)
        {

            OCFabrics = new ObservableCollection<Fabric>();

            OCFabrics.Add(new Fabric("fabric1", 5));
            OCFabrics.Add(new Fabric("fabric2", 5));
            OCFabrics.Add(new Fabric("fabric3", 5));

but my ViewModel doesn’t care what the Fabrics are or where they come from (memory, disk, the cloud?). It just wants to get all the fabrics.

You can rewrite this as

var allFabrics = FabricsDataService.GetAllFabrics();

The MVVMHelpers also has an ObservableRangeCollection that gives you extra methods like ​AddRange() since ObservableCollection only has Add() so you end up writing less code.

Now we can do

var allFabrics = FabricsDataService.GetAllFabrics();
OCFabrics.AddRange(allFabrics);

Now all we have to do is implement GetAllFabrics().

Introducing my biggest mental hurdle to MVVM

Okay here’s my biggest mental hurdle… what is FabricsDataService? I mean what sort of class is this? Where do I “new it up” or instantiate it? Turns out you’d either want to use a singleton class design pattern or just a static class. Since I’m learning to crawl towards MVVM, I’m going with static class since it is the easiest for me to conceptualize.

My next question is “where is this list of Fabrics stored in memory for other parts of my app to use?” Turns out it isn’t stored anywhere per-se. When my Page2 needs it, that page will simply called the data service. It seems redundant to me to keep new’ing up a List of fabrics on demand, especially if those are coming from disk or a web service. But I’ve had several people advise me to get past this idea that I need an app-wide List as the source of truth and instead rely on a (Fabric)DataService. I guess it’s the difference between fast food (my app-wide List vs “made to order” DataService. But then again, I remember being told all throughout my professional development days global variables are bad… so hello FabricDataService!

First, make FabricDataService a static class

public static class FabricDataService

and remove the default constructor (since it’s static).

Now back to our GetAllFabrics()… where do we get the data from? Since this is just about using the FabricDataService, we’re going to just new up those 3 fabric objects, e.g.

public static List<Fabric> GetAllFabrics()
        {

            List<Fabric> fabrics = new List<Fabric>();

            fabrics.Add(new Fabric("fabric1", 5));
            fabrics.Add(new Fabric("fabric2", 5));
            fabrics.Add(new Fabric("fabric3", 5));

            return fabrics;
        }

And now let’s rock on and hit Run (or whatever F5 translates to a Mac). And we get…

Fabrics displayed in ListView coming from DataService

Boom goes the dynamite!

But what about adding? Since we’re using ItemDetailsPage for both editing and adding, we have to check whether we’re editing a new item and respond accordingly. For example, in ItemDetailsViewModel,

        private async void DoneEditing()
        {
            if (isNew) {

                FabricsDataService.AddFabric(this.Fabric);

                MessagingCenter.Send<ItemDetailsViewModel, Fabric>(this, "added", this.Fabric);
            } else {

                FabricsDataService.UpdateFabric(this.Fabric);

            }

            await Navigation.PopAsync();
        }

Which now begs the question… what is the FabricDataService updating? We already said we didn’t want to use some app-wide global List as our source of truth. So what is the source of truth for the DataService????

This question is also known as my #2 biggest hurdle learning MVVM, which I’ll address in my next blog post: Application.Current.Properties versus Settings plugin.

One thought on “Sara can has DataService – Part 6 – Writing a Xamarin.Forms app

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s