Example project - Xamarin Fast Food

First of all, we can create a new Xamarin.Forms PCL project and reuse the same base structure that we created in Chapter 4, Data – the Monkeys Catalog.

We can copy all the classes we've written inside the Base folder and we can prepare the empty subfolders of Core to define the business logic of our project.

To use the Base classes, we need to import into 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 in the Packages folder. To update the package, right-click on the Packages folder and select Update from the contextual menu.

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

  • Name
  • Price
  • RequiredSeconds

The class will be developed as follows:

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 using the same structure that we learnt earlier in the book.

In the 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 this:

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 makes the request wait for the required time. We will change the base service later in the chapter 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.

Tip

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 a 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 now have 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 a label here 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. We will develop, later in the chapter, a call to a remote service. 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 ("
Received: {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 on the Droid project and, in the Android Application section, check the ReadExternalStorage and WriteExternalStorage permissions:

Presentation Layer

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;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.40.177