-
-
-
-
URL copied!
These days, ReactiveX is the most popular approach to take for asynchronous programming. Focusing on mobile development, it is the best way to call to any API and manage data using Observer pattern.
Light introduction to Rx
If you already have knowledge in Rx, jump to the next section of this article.
ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.
If you want to learn more about Rx, please check this post:
Observer’s implementation
One of the types more used is Observable. Then that observer reacts to whatever item or sequence of items the Observable emits. This pattern facilitates concurrent operations because it does not need to block while waiting for the Observable to emit objects, but instead it creates a sentry in the form of an observer that stands ready to react appropriately at whatever future time the Observable does so.
The Subscribe
method is how you connect an observer to an Observable. Your observer implements some subset of the following methods:
- onNext: An Observable calls this method whenever the Observable emits an item. This method takes as a parameter the item emitted by the Observable.
- onError: An Observable calls this method to indicate that it has failed to generate the expected data or has encountered some other error. It will not make further calls to
onNext
oronCompleted
. This method takes as its parameter an indication of what caused the error. - onCompleted: An Observable calls this method after it has called
onNext
for the final time, if it has not encountered any errors.
Defining project structure
First of all, I want to share with you a basic project structure, taken from Android pattern:
This structure has three folders that include all functionality
- Data: contains the access to repositories, like databases, api calls, cache, entity. Also, includes the mappers to transform an entity to a model class
- Domain: contains the business model, the use cases and expose the repositories (as interfaces)
- Presentation: this is the UI. This contains the views and viewmodel or presenter classes (depending of the chosen pattern)
The communication flow should be:
Presentation <-> Domain <-> Data
Integrating Rx.NET in Xamarin
Up to here, we have learned about Rx in general. Now, we will focus in how we can implement this in Xamarin. For do that, we will need add Rx.NET
plugin to our project (and all referenced projects)
Let’s think in a basic app that populates a data in a list view. So, the first step is call from our UI to retrieve data. I’ll base in a sample that shows a list of cities.
We call to our Presenter to retrieve the data
Then, from our Presenter we need to call to our use case
public void LoadCities(bool forced)
{
var useCache = !forced;
UseCase.Execute(new CityListObserver { Presenter = this}, new Params { UseCache = useCache });
View.OnLoadingStart();
}
Keep in mind, we need to provide an Observer to listen any changes on data.
class CityListObserver : DefaultObserver<List<City>>
{
public CityPresenter Presenter { get; set; }
public override void OnCompleted()
{
// Do nothing for now...
}
public override void OnError(Exception error)
{
if (error.InnerException is HttpRequestException && !App.IsNetworkAvailable())
{
Presenter.View.OnNetworkDisabledError();
}
else
{
Presenter.View.RenderError(error);
}
}
public override void OnNext(List<City> value)
{
Presenter.View.Render(value);
}
}
So, the next step is our Use Case. This will call to repositories
public class GetAllCitiesUseCase : UseCase<List<City>, Params>
{
ICityRepository Repository = new CityRepository();
public override IObservable<List<City>> BuildUseCaseObservable(Params param)
{
return Repository.Cities(param.UseCache);
}
}
public class Params
{
public bool UseCache { get; set; }
}
A repository can be any datastore we have. This is the common repository class to ask to a concrete repository to retrieve the data:
public class CityRepository : ICityRepository
{
CityMapper Mapper = new CityMapper();
CityDataStoreFactory Factory = new CityDataStoreFactory();
public IObservable<List<City>> Cities(bool useCache)
{
var dataSource = Factory.Create(useCache);
var entities = dataSource.Cities();
return entities.Select(x => Mapper.TransformList(x));
}
}
In this repository, we create the concrete DataSource using a Factory. In addition, we are using the Select method to transform each elements of CityEntity list to City list, through to our Mapper. This is how we apply map operator in C#.
This is a local implementation of DataStore:
public class DiskCityDataStore : ICityDataStore
{
public ICityCache CityCache { get; set; }
public IObservable<List<CityEntity>> Cities()
{
return Observable.Create<List<CityEntity>>((emitter) =>
{
var list = CityCache.GetAll();
if (list != null)
{
emitter.OnNext(list);
emitter.OnCompleted();
}
else
{
emitter.OnError(new Exception("Cities were not found"));
}
return () => { };
});
}
}
There, we create an Observable object from our local data.
And that is! We have created a basic flow using Rx.NET library. You can see the full sample in this repo. Feel free to contribute, file issues or suggestions! Let’s make a better architecture 😉
Top Insights
Escribiendo User Stories en Agile
AutomotiveCommunicationsConsumer and RetailFinancial ServicesHealthcareManufacturing and IndustrialMediaTechnologyWhat is TM Forum Frameworx and how to...
UncategorizedAutomotiveCommunicationsConsumer and RetailFinancial ServicesHealthcareManufacturing and IndustrialMediaTechnologyImpact Mapping en Metodologías ágiles
AutomotiveCommunicationsConsumer and RetailFinancial ServicesHealthcareManufacturing and IndustrialMediaTechnologyTop Authors
Blog Categories
Trabajemos juntos
Contenido Relacionado
5 razones por las que tu proyecto necesita un Business Analyst
Contar con un Business Analyst (BA) en tu equipo no solo te ayudará a delegar tareas más operativas, sino que también potenciará al equipo de desarrollo y contribuirá significativamente al éxito de tu proyecto de desarrollo de software.
Conocer más
7 claves para ser un miembro de un equipo efectivo
Un gran desarrollador necesita trabajar tanto en sus habilidades técnicas como en sus habilidades blandas, ya que estas forman la base para cualquier profesional que quiera ser una pieza efectiva e inspirar un cambio positivo en su equipo y organización. He recopilado una serie de recomendaciones que considero básicas y de vital importancia para trabajar … Continue reading Xamarin.Forms + Clean Architecture + Rx.NET →
Conocer más
Share this page:
-
-
-
-
URL copied!