Xamarin applications can benefit from improved performance by using Lazy in the constructor. In this article, you’ll learn how to implement it and use it easily.
The problem with Dependency Injection in Xamarin is Performance
With the MVVM architecture pattern, we use a SDK to do our resolving for us. Packages such as Unity, Prism and FreshMvvm are popular. However, they all use Reflection to help with the resolving. The problem with Reflection is that it takes time to resolve.
Depending on the chosen package, resolving can take hundreds of milliseconds and that is a bad thing for a mobile app. It makes the experience slow and unresponsive. It can get even worse, if the injected interface has other interfaces in it’s constructor.
Improving Xamarin Performance with Lazy helps screen load times.
Watch out for Circular Dependencies
In spaghetti code, circular dependencies can arise. For instance, a ViewModel could pull in a Repository. The Repository could pull in a DataSource and that DataSource could pull in the same Repository. In this simple example, if the implementations were not using the interface apart from some edge case, then the app would simply crash in a stack overflow. Using the Lazy<T> will help protect from this as they are resolved ONLY when they are used for the first time.
NOTE: Using Lazy<T> is not an answer to Circular Dependencies but it’s useful to be aware of them.
Why be Lazy
The main reason for using Lazy is to improve speed. Delaying the creation so the app can render the screen faster. A fast app is a good app.
How to be Lazy
This is how we write our code out using Lazy to improve performance.
public class MainViewModel { private Lazy<ISomeRepository> _lazySomeRepository; private ISomeRepository SomeRepository => _lazySomeRepository.Value; public MainViewModel(Lazy<ISomeRepository> lazySomeRepository){ _lazySomeRepository = lazySomeRepository; } public void RefreshData(){ var allData = SomeRepository.GetAllData(); ..... } }
From the code, you can see that we store the injected interface as a private member. Most DI packages such as Unity support Lazy and handle the resolving for you. If you’re currently using DI, check with the documentation.
What about Unit Tests?
Lazy works with Unit tests. If you mock your implementation, simply add the new Lazy<T>(mockObject.Object) and it will just work.
Lazy is as Lazy does
Reflection is the enemy of Mobile applications. Reducing Reflection use improves performance.
Be sure not to do too much in a Constructor and you’ll keep your app humming along nicely.