6 min read

In this article by Matteo Bortolu and Engin Polat, the author of the book Xamarin 4 By Example, we are going to create a new projects called fast food with help of Service and Presentation layer.

(For more resources related to this topic, see here.)

Example project – Xamarin fast food

First of all, we create a new Xamarin.Forms PCL project. Prepare the empty subfolders of Core to define the Business Logic of our project.

To use the Base classes, we need to import on our projects the SQLite.Net PCL from the NuGet Package manager. It is a good practice to update all the packages before you start. As soon as a new package has been updated, we will be notified on the Packages folder. To update the package right click on the Packages folder and select Update from the contextual menu.

We can create, under the Business subfolder of the Core, the class MenuItem that contains the properties of the available Items to order. A MenuItem will have:

  • Name
  • Price
  • Required seconds.

The class will be developed as:

public class MenuItem : BaseEntity<int> {
  public string Name {
    get;
    set;
  }
  public int RequiredSeconds {
    get;
    set;
  }
  public float Price {
    get;
    set;
  }
}

We will also prepare the Data Layer element and the Business Layer element for this class.

In first instance they will only use the inheritance with the base classes.

The Data layer will be coded like this:

public class MenuItemData : BaseData<MenuItem, int>
{
public MenuItemData ()
{
}
}

and the Business layer will look like:

public class MenuItemBusiness : BaseBusiness<MenuItem, int>
{
  public MenuItemBusiness () : base (new MenuItemData ())
  {
  }
}

Now we can add a new base class under the Services subfolder of the base layer.

Service layer

In this example we will develop a simple service that make the request wait for the required seconds. We will change the bsssssase service later in the article in order to make server requests.

We will define our Base Service using a generic Base Entity type:

public class BaseService<TEntity, TKey>
where TEntity : BaseEntity<TKey>
{
  // we will write here the code for the base service
}

Inside the Base Service we need to define an event to throw when the response is ready to be dispatched:

public event ResponseReceivedHandler ResponseReceived;
public delegate void ResponseReceivedHandler (TEntity item);

We will raise this event when our process has been completed. Before we raise an event we always need to check if it has been subscribed from someone. It is a good practice to use a design pattern called observer.

A design pattern is a model of solution for common problems and they help us to reuse the design of the software.

To be compliant with the Observer we only need to add to the code we wrote, the following code snippet that raises the event only when the event has been subscribed:

protected void OnResponseReceived (TEntity item)
{
  if (ResponseReceived != null) {
    ResponseReceived (item);
  }
}

The only thing we need to do in order to raise the ResponseReceived event, is to call the method OnResponseReceived.

Now we will write a base method that gives us a response after a number of seconds that we will pass as parameter as seen in the following code:

public virtual asyncTask<TEntity>GetDelayedResponse(TEntity
  item,int seconds)
{
  await Task.Delay (seconds * 1000);
  OnResponseReceived(item);
  return item;
}

We will use this base to simulate a delayed response.

Let’s create the Core service layer object for MenuItem. We can name it MenuItemService and it will inherit the BaseService as follows:

public class MenuItemService : BaseService<MenuItem,int>
{
  public MenuItemService ()
  {
  }
}

We have now all the core ingredients to start writing our UI.

Add a new empty class named OrderPage in the Presentation subfolder of Core.

We will insert here a label to read the results and three buttons to make the requests:

public class OrderPage : ContentPage
{
  public OrderPage () : base ()
  {
    Label response = new Label ();
    Button buttonSandwich = new Button 
    {
      Text = "Order Sandwich"
    };
    Button buttonSoftdrink = new Button
    {
      Text = "Order Drink"
    };
    Button buttonShowReceipt = new Button
    {
      Text = "Show Receipt"
    };
    // ... insert here the presentation logic
  }
}

Presentation layer

We can now define the presentation logic creating instances of the business object and the service object. We will also define our items.

MenuItemBusiness menuManager = new MenuItemBusiness ();
MenuItemService service = new MenuItemService ();
MenuItem sandwich = new MenuItem {
  Name = "Sandwich",
  RequiredSeconds = 10,
  Price = 5
};
MenuItem softdrink = new MenuItem {
  Name = "Sprite",
  RequiredSeconds = 5,
  Price = 2
};

Now we need to subscribe the buttons click event to send the order to our service.

The GetDelayedResponse method of the service is simulating a slow response. In this case we will have a real delay that depends on the network availability and the time that the remote server needs to process the request and send back a response:

buttonSandwich.Clicked += (sender, e) => {
  service.GetDelayedResponse (sandwich, sandwich.RequiredSeconds);
};
buttonSoftdrink.Clicked += (sender, e) => {
  service.GetDelayedResponse (softdrink,
softdrink.RequiredSeconds);
};

Our service will raise an event when the response is ready.

We can subscribe this event to present the results on the label and to save the items in our local database:

service.ResponseReceived += (item) => {
  // Append the received item to the label
  response.Text += String.Format ("nReceived: {0} ({1}$)",
  item.Name,
  item.Price);
  // Read the data from the local database
  List<MenuItem> itemlist = menuManager.Read ();
  //calculate the new database key for the item
  item.Key = itemlist.Count == 0 ? 0 : itemlist.Max
  (x => x.Key) + 1;
  //Add The item in the local database
  menuManager.Create (item);
};

We now can subscribe the click event of the receipt button in order to display an alert that displays the number of the items saved in the local database and the total price to pay:

buttonShowReceipt.Clicked += (object sender, EventArgs e) => {
  List<MenuItem> itemlist = menuManager.Read ();
  float total = itemlist.Sum (x => x.Price);
  DisplayAlert (
    "Receipt",
    String.Format(
      "Total:{0}$ ({1} items)",
      total,
      itemlist.Count),
    "OK");
};

The last step is to add the component to the content page:

Content = new StackLayout {
  VerticalOptions = LayoutOptions.CenterAndExpand,
  HorizontalOptions = LayoutOptions.CenterAndExpand,
  Children = {
    response,
    buttonSandwich,
    buttonSoftdrink,
    buttonShowReceipt
  }
};

At this point we are ready to run the iOS version and to try it out. In order to make the Android version work we need to set the permissions to read and write in the database file.

To do that we can double click the Droid project and, under the section Android Application, check the ReadExternalStorage and WriteExternalStorage permissions:

In the OnCreate method of the MainActivity of the Droid project we also need to:

  1. Create the database file when it hasn’t been created yet.
  2. Set the database path in the Configuration file.
var path = System.Environment.GetFolderPath (
  System.Environment.SpecialFolder.ApplicationData
);
if (!Directory.Exists (path)) {
  Directory.CreateDirectory (path);
}
var filename = Path.Combine (path, "fastfood.db");
if (!File.Exists (filename)) {
  File.Create (filename);
}
Configuration.DatabasePath = filename;

Summary

In this article, we have learned how to create a project in Xamarin with the help of Service and Presentation layer. We have also seen that, how to set read and write permissions to make an Android version work.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here