Building a Kubernetes dashboard using Xamarin Forms

On and off over the past 6 months, I have been living in the world of Xamarin Forms to build a cross platform mobile app; with the plan to move to learning native Android and iOS development afterwards.

For those who haven’t come across Xamarin before, it is a cross platform technology from Microsoft that allows you to build native Android and iOS applications using C# and .NET. Xamarin Forms provides a UI toolkit allowing you to define UI code for both platforms.

I really liked using Xamarin Forms for what I was building, but just found every now and again you had to deal with some pain like:

  • Upgrading Android Support NuGet Packages.
  • Debugging exceptions that give no detail.
  • Working out why XAML fails to compile.

But you have to forgive it, given what magic Xamarin is doing under the covers.

Anyway during that time I read pretty much all the documentation and came across useful resources that showed me the right direction to, so I thought I would share them.

An aside … introducing kubemob

Prior to diving into Xamarin Forms I was playing around with Kubernetes (which you can read more about here); this gave me the idea of building the equivalent of Kubernetes Dashboard as an Android and iOS app.

When developing this application, I tried to closely match the Kubernetes Dashboard experience:

Clusters page
Cluster Overview page
Pods page
Pod Detail page

Currently the app just supports viewing Kubernetes resources, and only Kubernetes clusters within Microsoft Azure subscriptions. However in the future (when I get more time), I would like to add:

  • Search
  • The ability to create, edit and delete resources.
  • Support for other clouds including AWS and Google Cloud Platform.

Architecture

This section focuses on the architecture of the app including design patterns.

Model View View Model (MVVM)

Xamarin Forms is built around the MVVM pattern and is pretty much unavoidable.

Xamarin provide a great deal of useful code sample to facilitate using MVVM which includes:

  • ExtendedBindableObject — a class that extends Xamarin Form’s built in INotifyPropertyChanged implementation with syntactic sugar.
  • ViewModelLocator — this automatically creates the corresponding view model for a page and sets its binding context. It also provides the means for a view model to do any initialization work, before it’s page is displayed.
  • EventToCommandBehavior — this behavior allows you to bind ICommands to view events, allowing you to be a “MVVM purest”.

Dependency injection

Using a dependency injection (DI) container goes hand in hand with using a ViewModelLocator, and provides the same benefits as when used elsewhere such as facilitating testability.

I know there are many DI containers out there, but I chose to go with ASP NET Core’s default dependency injection framework. The reason is that Microsoft.Extensions.DependencyInjection is very easy to setup and is not bloated with hundreds of features that I won’t use like Autofac.

Navigation service

Again in trying to be pure MVVM, view models shouldn't know about UI specifics. In the case of Xamarin Forms, navigation is done by manipulating a stack of page types.

To abstract navigation away, I created a NavigationService class but in contrast to the documentation I prefer to have explicit methods to navigate to pages; in contrast to using view model types to drive which page to go to.

Configuration

The AppSettings class contains all the user settings used throughout kubemob; this follows the configuration management pattern discussed here:

Validation

When a user tries to add an Azure account, validation is performed to ensure that all entries are populated.

Any errors that occur need to be feedback to the user and the setup shown on the following link, is easily expandable for any validation rule you can think of.

Localization

Although I’m not supporting multiple languages currently, I think it’s best to set it up from the beginning as in the long run, it will save a lot of time and work later on when you do have to support other languages.

Performance

This section focuses on techniques you can do to improve performance of an application and decrease the app size.

Enable XAML compilation

XAML compilation is a feature in Xamarin Forms that enables compile time checking of XAML and it also removes some of the load and instantiation time, as well as reduces the final app size.

You can enable it app-wide by adding the XamlCompilation attribute to App.xaml.cs

Configure the linker (and other tips)

There are a great number of tips to improve the performance of your Xamarin Android or iOS applications as discussed here.

One of the most notable is the Linker which can help reduce the size of the application by removing unused code.

One recommendation I have is to enable Link All from day one, even in Debug mode. The reason I recommend this is that it enables you to catch any errors during development, when the Linker actually removes code that is required.

If its your code you can use the PreserveAttribute to ensure the code isn’t removed; whereas if its a NuGet package you can specify in the project settings for Linker to ignore certain assemblies(Android / iOS).

List view performance

kubemob uses quite a few list views to display data throughout the application and if you aren’t careful, they can appear sluggish.

There are number of different techniques discussed here to ensure any list views stay responsive.

Use layout compression

When you have complicated layouts, you can improve the page rendering performance by using layout compression.

This aims to flatten the view nesting by removing specified layouts from the visual tree.

Use native HttpClient and SSL/TLS stacks

By default, for compatibility reasons, Xamarin Forms uses the HTTP stack from .NET.

However the native stacks have increased performance and by using them help decrease the overall app size, so its recommended to switch to the native stacks.

Android — Use fast renderers

Due to the way the original control renderers on Android work, they have a performance implication due to each control being composed of two views.

To resolve this, fast renderers can be enabled which improve performance by creating fewer objects.

iOS — Use LLVM code generation engine

During the build of a Xamarin Forms application, code is generated for the target platform.

On iOS, you can switch the code generation engine to use LLVM which produces both faster and tighter code than the Mono engine does, at the cost of longer compile times.

UI

This final section discusses re-usable components that can help make developing Xamarin Forms UIs easier.

EffectBehavior

EffectBehavior in the Xamarin documentation simplifies the boilerplate code you have to write to apply an Effect to a control; kubemob’s version extends it with support for adding an Effect based on a bindable condition.

This came in handy when adding a validation error effect to invalid entries in a form.

ItemsControl

If you come from a WPF background, you might end up looking for an ItemsControl. There is no built in one in Xamarin Forms, however there is a sample one in the Xamarin University Infrastructure library on GitHub.

WrapLayout

Similarly to ItemsControl, the Xamarin University Infrastructure library also provides a WrapLayout implementation.

I hope you found these resources useful as I did and if there are any you think I have missed, please do let me know.