Skip to content
This repository has been archived by the owner on Nov 22, 2018. It is now read-only.

Article

Hein Pauwelyn edited this page Mar 25, 2017 · 3 revisions

TL;DR

Introduction

I've made an application that works on Windows Universal 10 devices. It gives the forecast for several cities in this world by an API (application programming interface) from Yahoo. It contains the MVVM (model view view-model) pattern (more specific MVVM light library) and IoC (inversion​ of control) architectures. I use also SQLite (structured query language lite) database for storing the search results. But what are there? Here comes some information:

MVVM (model view view-model)

MVVM is a software architectural pattern and it's build in tree parts like it said. In your project you have tree parts: models, views and view-models like show on image below.

image

The models go access the database, but for this project I use API's from Yahoo mapped into the folder Repositories.

View-models contains ICommands and some binding properties. All view models inherit form ViewModelBaseClass where the interface INotifyPropetyChanged​ has been implemented.

The last part are the views. This contains the XAML pages and data templates. The last one is stored into the folder DataTemplates.

Each part is communicate witch each other:

  • The views with the view models,
  • The view models with the models (and repositories),
  • The repositories access the API (or another data source).

In theories is this correct, but in practical situations communicate the view also with the models. This must be for the data bindings of the element properties to the model properties.

On the image there stand also a fourth part named unit tests. This are tests you can make for testing your code. This is not implement in the project and not explained in this article.

IoC-container (inversion​ of control container)

IoC containers are container with basic functionality needed to register and resolve instances. For the project we go use the SimpleIoc class from MVVM light. The methods we go use in these project are:

Name Description
Register<TClass>(Boolean) Registers a given type with the possibility for immediate creation of the instance.
GetInstance<TService>() Provides a way to get an instance of a given type. If no instance had been instantiated before, a new instance will be created. If an instance had already been created, that same instance will be returned. Remark: If the class is not registered, the method will return null.

For more information and methodes you can read the documentation on mvvmlight.net.

There is also a default constructor without parameters that initializes a new instance of the SimpleIoc class.

Dependency injection or DI

Dependency injection is a way of working that allow you to make code independent of the class where you are working on. For this you can use interfaces. Thy defined only the signature of the methods, properties and variables. An example you can use is to use a dummy class when developing or a web service when deploying. Here you've a code expample:

public interface IDataSource
{
    IEnumarble<object> Get(); // used for get all the objects
}

public class DummySource : IDataSource
{
    public IEnumarble<object> Get()
    {
        return new List<object> {
            new { Letter = "A", Number = "1" },
            new { Letter = "A", Number = "1" }
        }
    }
}

public class WebSource : IDataSource
{
    public IEnumarble<object> Get()
    {
        //return all objects of a web service 
    }
}

On the place where you call the Get() method, it doesn't matter what the class is. It could be the dummy class or the webservice.

Note: on the place where you call the method, don't use the classes but use the interface like code below:

IDataSource source = new DummySource();
IEnumarble<object> dummyData = source.Get();

source = new WebSource();
IEnumarble<object> webData = source.Get();

This code will work because the variable source, is independent from the class DummySource and WebSource because I've made a "wrapper" interface named IDataSource that have a signature of the methodes.

Building the app

Making of the solution

In the solution I've made three projects named:

  1. Data contains repositories for access the API. Download the NuGet Newtonsoft.Json package for this project.
  2. Models contains the classes we needed
  3. UWP what stands for universal Windows 10 project and has following folders:
    • Assets is default folder added in the project and contains images for the logo into the Windows store.
    • DataTemplates for store data templates
    • Pages contains the pages we go use
    • Services contains the IoC container
    • ViewModels contains the view models and one folder ​​ * core for store the core data

We also need some NuGet packages you can download it from the NuGet manager. For the data project is this Newtonsoft.JSON and for the UWP project we need MvvmLight.

Making of the pages

If the UWP project is made, you see next items into that project

  • Properties contains the properties of that project.
  • References contains the references needed for that project.
  • The folders we've just created.
  • App.xaml contains important recourses and information about your project.
  • MainPage.xaml is the first page that is show when the application run.
  • Package.appxmanifest
  • project.json
  • Wheater.UWP_TemporaryKey.pfx

First we need MainPage.xaml.

Use of API's (application programming interface)

An API is a service for getting routines, protocols, tools or data powered by other instances (like Yahoo) that software programmers can access into there programs, applications and websites. But can find by robots, Dominica, drones and much more.

The first URL we need

First of all we must access the API from Yahoo to get the data from. The URL (uniform recourse locator) that we go use is this:

https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places%20where%20text%3D%22@placemame%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys

I've found the URL on developer.yahoo.com/weather/. You see the parameter q what is a SQL statement:

SELECT *
FROM weather.forecast
WHERE woeid 
IN (SELECT woeid
    FROM geo.places
    WHERE text = @placemame)

This go select all the fields of the table weather.forecast where woeid (WOEID stands for where on earth identifier) is equal with the value of the select from the table geo.places where the text field is equal to variable @placename. This variable must have a value so that the URL is valid in this case is this a string or for say it into SQL language is this from the type nvarchar or text depended from the used SQL language by Yahoo.

On the URL above you can also see a second parameter called format. For this example we go use JSON (JavaScript object notation) as receiving value.

Convert JSON code to C# classes

If you navigate to to the URL you see this JSON code. Here you've the forecast from March 1st 2016 from Meenen, Belgium:

{  
   "query":{  
      "count":1,
      "created":"2016-03-01T17:31:15Z",
      "lang":"en-US",
      "results":{  
         "channel":{  
            "title":"Yahoo! Weather - Meenen, BE",
            "link":"http://us.rd.yahoo.com/dailynews/rss/weather/Meenen__BE/*http://weather.yahoo.com/forecast/FRXX4403_f.html",
            "description":"Yahoo! Weather for Meenen, BE",
            "language":"en-us",
            "lastBuildDate":"Tue, 01 Mar 2016 6:00 pm CET",
            "ttl":"60",
            "location":{  
               "city":"Meenen",
               "country":"Belgium",
               "region":""
            },
            "units":{  
               "distance":"mi",
               "pressure":"in",
               "speed":"mph",
               "temperature":"F"
            },
            "wind":{  
               "chill":"37",
               "direction":"200",
               "speed":"20"
            },
            "atmosphere":{  
               "humidity":"93",
               "pressure":"29.83",
               "rising":"0",
               "visibility":"3.73"
            },
            "astronomy":{  
               "sunrise":"7:28 am",
               "sunset":"6:30 pm"
            },
            "image":{  
               "title":"Yahoo! Weather",
               "width":"142",
               "height":"18",
               "link":"http://weather.yahoo.com",
               "url":"http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"
            },
            "item":{  
               "title":"Conditions for Meenen, BE at 6:00 pm CET",
               "lat":"50.8",
               "long":"3.12",
               "link":"http://us.rd.yahoo.com/dailynews/rss/weather/Meenen__BE/*http://weather.yahoo.com/forecast/FRXX4403_f.html",
               "pubDate":"Tue, 01 Mar 2016 6:00 pm CET",
               "condition":{  
                   "code":"26",
                   "date":"Tue, 01 Mar 2016 6:00 pm CET",
                   "temp":"45",
                   "text":"Cloudy"
               },
               "description":"\n<img src=\"http://l.yimg.com/a/i/us/we/52/26.gif\"/><br />\n<b>Current Conditions:</b><br />\nCloudy, 45 F<BR />\n<BR /><b>Forecast:</b><BR />\nTue - Showers Late. High: 48 Low: 42<br />\nWed - PM Rain/Wind. High: 48 Low: 36<br />\nThu - Showers/Wind. High: 44 Low: 34<br />\nFri - Showers. High: 45 Low: 31<br />\nSat - PM Showers. High: 46 Low: 33<br />\n<br />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Meenen__BE/*http://weather.yahoo.com/forecast/FRXX4403_f.html\">Full Forecast at Yahoo! Weather</a><BR/><BR/>\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)<br/>\n",
               "forecast":[  
                  {  
                     "code":"45",
                     "date":"1 Mar 2016",
                     "day":"Tue",
                     "high":"48",
                     "low":"42",
                     "text":"Showers Late"
                  },
                  {  
                     "code":"12",
                     "date":"2 Mar 2016",
                     "day":"Wed",
                     "high":"48",
                     "low":"36",
                     "text":"PM Rain/Wind"
                  },
                  {  
                     "code":"11",
                     "date":"3 Mar 2016",
                     "day":"Thu",
                     "high":"44",
                     "low":"34",
                     "text":"Showers/Wind"
                  },
                  {  
                     "code":"11",
                     "date":"4 Mar 2016",
                     "day":"Fri",
                     "high":"45",
                     "low":"31",
                     "text":"Showers"
                  },
                  {  
                     "code":"39",
                     "date":"5 Mar 2016",
                     "day":"Sat",
                     "high":"46",
                     "low":"33",
                     "text":"PM Showers"
                  }
               ],
               "guid":{  
                  "isPermaLink":"false",
                  "content":"FRXX4403_2016_03_05_7_00_CET"
               }
            }
         }
      }
   }
}

Of course you could make the correct C# classes manually, but on the internet, you have some easy tools that do this for you. One of they is json2csharp.com (only to C#) or jsonutils.com (many other languages) that convert all the code for you. Import the classes to your project by copy past them and rename RootObject to YahooWheater.

Use the of API in the app

Make a new class into the data project named WebRepo and place this code for use the API.

public class WebRepo
{
    public static async YahooWeather GetData(string placename)
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                string url = $@"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places%20where%20text%3D%22{placemame}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

                string yahooGeoJSON = await client.GetStringAsync(url);
                return JsonConvert.DeserializeObject<YahooWeather>(yahooGeoJSON); 
            }
        }
        catch
        {
            return null;
        }
    }
}

Later we'll make dependency injection for this class.

Also posted on CodeProject