Xamarin MVVM Architecture – Part 1: Practical Code Separation

LinkedInTwitterGoogle+FacebookRedditEmail

At the time of writing, I’m pretty new to using Xamarin in a professional context. I’ve been fiddling with it on and off for a few years now, and have had the opportunity to use it for a few projects this year. I’ve learned a few rather important things, that I’d like to share in a series of posts, as they are related to your project’s square zero – architecture.

It is important to realize that one of the largest differences between Xamarin based architecture and “normal” mobile project architecture (Xcode, etc), is that we’re no longer operating in the world of Model-View-Controller (MVC). Rather, we are in the brave new world of Model-View-ViewModel (MVVM). This change means we’ll need to rethink most of what we already know about architecting mobile applications. Trust me when I say it’s far better to adjust early on, than try to shoe Xamarin into the MVC mindset.

When I was first researching Xamarin, the graphics on this page (and its previous iterations) made a profound impact on me. As I had been developing native mobile software professionally for some years, I quickly saw the benefits of a shared “core”. Think about how many times a service will change on you. Think about how many times a model is altered. Think about how many times the business logic is changed, due to feature requests, or fundamental misunderstandings. Staying agile and being able to adapt to these changes can make or break projects. When you are supporting just one platform, say, iOS, it is reasonably manageable. But once you throw another one into the works, and then another, it quickly becomes a nightmare. All of your work is duplicated. All of your bug fixes need to be verified multiple times. Having one platform functioning fine is not sufficiently indicative of whether or not all platforms are bug free. A relief from these worries is elegantly portrayed on the aforementioned page.

As I played with toy projects, and progressed through Xamarin University, I would architect my projects like so:

 

  • Solution: ProjectName
    • Project: ProjectName.iOS
    • Project: ProjectName.Android
    • Project: ProjectName.Shared

 

As these were small scale exercises, it wasn’t a big deal. Then, when Xamarin.Forms was announced, I took to essentially replacing the Shared project with the Forms project, as illustrated:

 

  • Solution ProjectName
    • Project: ProjectName.iOS
    • Project: ProjectName.Android
    • Project: ProjectName.Forms

 

In both situations, Shared or Forms would house ALL of the reusable code. Strictly speaking, this was a complete upgrade from managing an Objective-C and a Java codebase simultaneously. However, there are some problems here, that may not be immediately apparent.

To understand our current shortcomings, it is important to examine one of Xamarin’s biggest strengths. In my opinion, it is NOT the fact that it is cross platform, rather, it is the fact that you’re writing C# code. That may paint me to be some C# fanboy, but I can assure you that you could not be further from the truth. Rather, we should think about what else can be created using C#:

 

  • Windows Phone applications (Universal App)
  • Windows desktop application (Universal App)
  • Windows desktop applications (WPF)
  • Mac desktop application (Xamarin.Mac)
  • Etc

 

Now, what do all of these apps have in common with the iOS and Android apps we’ve written? Well, they all have models, persistence, networking, business logic, test suites, and tons of other stuff.

Can you see the problem now? What if someone asked you to go ahead and slap a WPF app on top of our nice “cross platform” codebase. Well.. that’s tricky. Because now, you are probably using Xamarin.Forms, which is a phenomenal tool, but it is probably all interconnected with your other stuff in the Shared / Forms project.

So, how do we maximize our code reuse, with consideration to either known other platforms, or possible future platforms? Well, we need to extract the items that are so sharable that they have nothing even to do with Xamarin.Forms. I’m talking about your ViewModels, your Models, your networking, and so on. We can simply break things up a bit:

 

Ideal Architecture

 

What we end up with here is an architecture that looks like the following, if you were to walk the levels from client applications down to a shared codebase:

 

At the cost of a bit more organizational overhead, we are now ready to take on essentially any platform in the future, that uses a C# codebase. Now, some of these may not appear, for example, the Net Solution. I’ve recently been using the Azure Mobile Services platform for my networking requirements, and as such, there has been no need to manually interact with HttpClient et al. And of course, the various client platforms you’re targeting will differ.

I’d strongly recommend that even if you’re targeting just one or two platforms, you consider using a similar approach from the beginning, when it is easiest. Not only does it allow you to quickly adapt to new requirements, but it also allows you to leverage the “wow” factor that Xamarin brings. Imagine if you have a spare couple of days and drop a full WPF app on top of your shared iOS and Android core? That will rock people’s worlds, I can attest to that.

 

We’ll revisit some of these architectural decisions in future posts, when we discuss some more in depth concepts, such as where to put different things, and in what way your dependencies should flow, but for now, I’d just like to thank all of you who’ve walked through this with me, and welcome all comments below. I think this is an great area of discussion that pushes the already incredible Xamarin to exciting new levels.

LinkedInTwitterGoogle+FacebookRedditEmail