Setting up your first ReactiveUI Project with Xamarin Forms

In this tutorial we go through the process of installing and setting up ReactiveUI 7 in Xamarin using the Model-View-View-Model pattern. Here, we'll take a high level look at all of the moving pieces we need in order to end up with an app that binds using ReactiveUI.

Installing ReactiveUI

We’ll begin by opening Visual Studio (or Xamarin studio) for mac. We’ll select `File->New Solution` and we’ll select Forms App. Click Next. Choose a name, we’ll target both Android and iOS, choose portable class library and I personally write my interfaces using C# but you can use XAML if that’s what you are comfortable with. We’ll move on to the next dialog and if we’re happy with were Visual Studio is saving our project, we’ll click create.

Once Visual Studio has finished loading our project we’ll go ahead and add our ReactiveUI packages.

Expand your Xamarin forms project and right click on packages and select `Add Packages…` Once the package manager dialog appears, search for RectiveUI, select the version you want to work with and click Add Packages. Accept the subsequent agreements and your packages should install without a problem. Next, go ahead and install the reactiveui-xamforms package. 

Once complete, double check that your packages look like this:

Screen Shot 2017-05-24 at 9.00.44 PM.png

Noticed that the package manager has automatically added the Rx and Splat dependences along with reactiveui and reactiveui-core.

Next, we’ll go ahead and add ReactiveUI to both our .Droid and .iOS projects as well. These steps are the same as with the forms project.

Just make sure that all of your package versions are exactly the same.

ReactiveUI Base Classes

Now that we have ReactiveUI installed we’ll set up our project using the MVVM pattern.

We’ll begin by adding two folders to our Xamarin Forms application. We’ll create a folder for our ContentPages, which we’ll call UserInterfaces and one for our ViewModels which we’ll call ViewModels. Once complete, your solution should look something like this.

Screen Shot 2017-05-24 at 9.21.42 PM.png

Next, we’ll add a pair of base classes. While this step isn’t necessary to use ReactiveUI, it does enforce a predictable pattern across our documents making them easier to work with over time.

We’ll start by right clicking on our ViewModels and we’ll select add file. We’ll create a new C# file which we’ll name ViewModelBase. Next we’ll add the following code.

    
// 1
public abstract class ViewModelBase : ReactiveObject, IDisposable where T : ReactiveObject, IDisposable 
{
    // 2
    protected readonly Lazy ViewModelBindings = new Lazy(() => new CompositeDisposable());
    // 3
    public bool IsDisposed { get; private set; }
    // 4
    protected abstract void RegisterObservables();
    // 5
    protected ViewModelBase()
    {
        RegisterObservables();
    }
    // 6
    #region IDisposable implementation
    public void Dispose()
    {
        if (!IsDisposed)
        {
            IsDisposed = true;
            Dispose(true);
            GC.SuppressFinalize(true);
        }
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)

        if (ViewModelBindings != null)
        {
            ViewModelBindings.Value.Dispose();
        }
    }

    #endregion
} 

This is a minimal version of a ViewModelBase class implementation that I learned from the mobile development experts at Eight Bot. This version, of course, is drastically stripped down compared to what one might use in production. But it will get us up and running for this exercise.

Let's take a high level look at what's going on here.

  1. We have an abstract class named ViewModelBase that offered a generic parameter. In ReactiveUI, all view model base classes must inherit from ReactiveObject, we are also implementing IDisposable. Finally, we're explicitly stating that our generic `T` parameter must implement both ReactiveObject and IDisposable.
  2. We’ve created a Lazy CompositeDisposable named ViewModelBindings. We’ll use this property to collect our ViewModels disposable subscriptions which get cleared out when our pages Dispose override method gets called. To learn more about CompositeDisposable check out the Introduction to Rx page on Disposables.
  3. We’re employing a boolean flag named IsDisposed to keep track of whether our objects have been disposed. This will keep us safe from disposing of an object more than once.
  4. RegisterObservables is an abstract method that we'll use to register our observables in our view model.
  5. Our class constructor which, in this simple example, simply calls our RegisterObservables method.
  6. Finally we take care of our disposables. This should be familiar to those who have spent any time using .Net. You can learn more about IDisposable here[3]

That does it for our ViewModelBase class. Once again, this is a simple version of what one might use in production but it is by no means production ready. Let’s go ahead and wire up a ContentPage base class using ReactiveUI.

Right click on your UserInterfaces folder and add a new C# file named ContentPageBase. Next, we’ll add the following code to out new file.

    
// 1
public abstract class ContentPageBase : ReactiveContentPage where TViewModel : ViewModelBase 
{   
    // 2
    protected Lazy ControlBindings = new Lazy(() => new CompositeDisposable()); 

    // 3 
    protected abstract void SetupUserInterface();
    protected abstract void BindControls();

    // 4
    protected ContentPageBase() : base()
    {   
        SetupUserInterface(); 
        BindControls();  
    }

    // 5
    protected override void OnDisappearing()
    {
        base.OnDisappearing();  
        UnbindControls(); 
    }  

    protected void UnbindControls()
    {  
        if (ControlBindings == null) return; 
        ControlBindings.Value.Clear();
    } 
}

 

As with our ViewModelBase, this ContentPageBase is a simplified example of what you might use in production.

Let’s break this down line by line.

  1. First and foremost, we are inheriting from ReactiveUI’s generic ReactiveContentPage class, which takes a generic type which is of type ViewModelBase.
  2. Here we are defining a lazy CompositeDisposable. We’ll use this property to collect our disposable subscriptions which get cleared out when our pages OnDisappearing override method gets called.
  3. We we are defining two abstract methods. One that will run our user interface code, and another that will bind our user interface controls to our View Model properties.
  4. Here we have our constructor, which calls SetupUserInterface followed by BindControls
  5. Next we call Xamarin Forms’ OnDisappearing method where we’ll remove our ControlBindings.

ReactiveUI in Action

Now we have everything we need to wire up a simple interface. We’ll begin by adding a new class which we’ll name `Dashboard.cs` to our ViewModels folder. Once our document has loaded we’ll make sure that our namespace to reflect our folder hierarchy to avoid collisions.

 
    
namespace YourAppName.ViewModels

We’ll inherit from our newly created ViewModelBase class and simply pass our Dashboard class type in as our type specifier. At this point Visual Studio will require that we implement our abstract base class, which is what we’ll do.

Before we move on, I want to point out that the goal of this exercise it for you to get up and running with ReactiveUI and MVVM. So I’ll forgo any in-depth explanation of the moving pieces you’re about to see. If you have any questions feel free to leave them in the comments section below.

Let’s go ahead and add the rest of our Dashboard class now.

    
public class Dashboard : ViewModelBase
{ 
    // 1
    string _statusMessage;

    [DataMember]
    public string StatusMessage
    {
        get { return _statusMessage; }
        private set { this.RaiseAndSetIfChanged(ref _statusMessage, value); }
    }

    ImageSource _currentImage;

    [DataMember]
    public ImageSource CurrentImage
    {
        get { return _currentImage; }
        set { this.RaiseAndSetIfChanged(ref _currentImage, value); }
    }

    [DataMember]
    public List ImageList { get; set; } = new List();
 
    [DataMember]
    public string Title
    {
        get { return "My Dashboard"; }
    }
    // 2
    public ReactiveCommand InitializeCommand { get; private set; } 

    // 3
    protected override void RegisterObservables()
    {
        // 4
	InitializeCommand = ReactiveCommand.CreateFromTask(async _ => 
	{
	    // initialization logic goes here 
	    StatusMessage = "Initializing";

	    // maybe we're getting images from a server 
	    await Task.Delay(1000); // but we should really use Task.Delay in our apps right?

	    StatusMessage = "Downloading";

	    // simulate a lengthy server response
	    await Task.Delay(3000); 

	    StatusMessage = "Go-Go Random Logos!";

	    ImageList.Add("xamagon.png");
	    ImageList.Add("eightbot.png");
	    ImageList.Add("reactivelogo.png");
	    ImageList.Add("codebeaulieu.png");
	    ImageList.Add("Rx_Logo_512.png");

	    await Task.Delay(1000);
	    await Task.FromResult(Unit.Default);

        }).DisposeWith(ViewModelBindings.Value);

        // 5
	Observable
	    .Interval(TimeSpan.FromMilliseconds(500))
	    .ObserveOn(RxApp.MainThreadScheduler)
	    .Select(_ =>
	    {
	        if (ImageList.Count == 0) 
		    return ImageSource.FromFile("reactivelogo.png");

		Random random = new Random();
		int number = random.Next(0, ImageList.Count);

		return ImageSource.FromFile(ImageList[number]); 
					 
	    }).BindTo(this, x => x.CurrentImage);
     }
 }

We’ll take a high level look at whats going on but we’ll spare the detail.

  1. We’ve included several properties that we’ll bind to in our Dashboard ContentPage.
  2. We’re including a status message which is of type string, current image which is a Xamarin Forms ImageSource, a List of strings that will hold a list of image names and title which is of type string.
  3. We’re including a ReactiveCommand which we’ll bind to in our ContentPage later.
  4. Next we have our RegisterObservables method which, if you recall from our base class implementation, gets called from our constructor.
  5. Here we have our ReactiveCommand implementation. When our command gets fired from our ContentPage, this is the logic that will execute.
  6. Finally, we have a Reactive observable that fires every have second and binds a random image to our CurrentImage property.
Important: In order for your application to run, you’ll need to add images to both your iOS and Droid projects respectful resource folders. If you are at a shortage of images, you can use the ones that I’ve included in this project by downloading them from my example project here.[4]

Alright, we’re almost there! Let’s finish up by adding a content page to our app. We’ll right click on our UserInterfaces folder and add another file named Dashboard.cs. Hopefully you remembered to change your namespace earlier or you’ll be sure to confuse the compiler.

The first thing we’ll do is inherit from our ContentPageBase and then we’ll pass in our view model dashboard type. The rest of the code for this demo, goes something like this:

    
public class Dashboard : ContentPageBase
{
    // 1
    Image _images;

    Label _status;

    //2
    public Dashboard()
    {
        ViewModel = new ViewModels.Dashboard(); 
    }

    //3
    protected override void SetupUserInterface()
    { 
        _status = new Label
        { 
            FontSize = 20,
	    FontFamily = Device.OnPlatform("AvenirNext-Medium", "Roboto", "Verdana"),
	    HorizontalTextAlignment = TextAlignment.Center,
	    VerticalTextAlignment = TextAlignment.Center,
	    HorizontalOptions = LayoutOptions.CenterAndExpand,
	    VerticalOptions = LayoutOptions.Center,
	    Margin = new Thickness(0,40,0,0)
        };

        _images = new Image {
	    HorizontalOptions = LayoutOptions.FillAndExpand,
	    VerticalOptions = LayoutOptions.FillAndExpand,
	    Aspect = Aspect.AspectFit, 
	    HeightRequest = 350 
        };

	Content = new StackLayout 
	{
	    HorizontalOptions = LayoutOptions.FillAndExpand,
	    VerticalOptions = LayoutOptions.FillAndExpand,
	    Padding = 20,
	    Children = { 
                _status,
		_images
	    }
        };
    }

    //4
    protected override void BindControls()
    {
        this.OneWayBind(ViewModel, vm => vm.Title, c => c.Title)
	    .DisposeWith(ControlBindings.Value);

	this.Bind(ViewModel, x => x.StatusMessage, c => c._status.Text)
            .DisposeWith(ControlBindings.Value);

        this.WhenAnyValue(x => x.ViewModel.CurrentImage)
            .BindTo(this, x => x._images.Source)
	    .DisposeWith(ControlBindings.Value);
        
        this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .InvokeCommand(this, x => x.ViewModel.InitializeCommand)
            .DisposeWith(ControlBindings.Value);
            
    } 
}

Since the goal is to demonstrate the pattern, we’ll take a high level look at the rest of the implementation.

  1. Here we have our user interface controls. We’ll be binding to these in a moment.
  2. Here we have our class constructor. We’re setting our ViewModel equal to our ViewModels.Dashboard file. ViewModel belongs to the ReactiveUI framework.
  3. Next, we’re calling our InitializeCommand on our freshly set view model and calling execute. This will execute our logic in our InitializeCommand implementation.
    User interface setup, nothing interesting here.
  4. And here is where the magic happens… We’re using three different binding statements to bind our interface controls to observables in our view model.

So, your code should be complaining right now since DisposeWith doesn’t actually exist in ReactiveUI! This is an extension method provided by Eight Bot in their public GitHub repository on Reactive-Extension, which you can find here.

Create a new folder in your application named Extensions and add a new class named IObservableExtensions. Add the following code.

 
    
 /*
    This extension was taken from Eight Bot's Reactive-Exampes repository with permission.
    url: https://github.com/TheEightBot/Reactive-Examples/blob/master/ReactiveExtensionExamples/Extensions/IObservableExtensions.cs
    author: Mike Stonis
    website: http://www.eightbot.com/
*/
public static class IObservableExtensions
{
    public static TDisposable DisposeWith(this TDisposable observable, CompositeDisposable disposables) where TDisposable : class, IDisposable
    {
        if (observable != null)
            disposables.Add(observable);

	return observable;
    }
}
      

Thanks to Mike Stonis for sharing gems like this.

And with that, we are ready to run our application.

 

 

Download project files from GitHub

How to add dynamic meta tags to your asp.net mvc views

Setting Up

We'll start by creating a new ASP.NET MVC 5 project and we'll make sure we have individual accounts selected. We're doing this so that we get entity framework and our dbcontext out-of-the-box. 

94f32fe3-cd15-473a-8872-884f09f545f1newProjectIndividualAccountsSelected.PNG

In your new project, let's create two models. We'll make a Page model and a MetaViewModel. The Page model will contain all of the properties that we'll be using in our database, the MetaViewModel will be used to shape the data for rendering our partial view. This will make perfect sense when you see it in context.

Adding Models

So let's create our Page.cs file in our model's folder and then we'll add the following code:

 
    
public class Page
{
    public int Id { get; set; }
    public string Author { get; set; }
    public string Keywords { get; set; }
    public string Description { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
}

and we'll go ahead an add our MetaViewModel as well in the same manor, here's the code:

    
public class MetaViewModel
{
    public string Author { get; set; }
    public string Keywords { get; set; }
    public string Description { get; set; }
}

Let's continue by adding our Page class to our dbcontext by creating a new property for it in our IdentityModels file (in your model folder). We're just going to add one line, like so:

    
public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext() 
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    public DbSet Pages { get; set; } // this is the line we're adding
}

Build your project but don't actually run it yet.

Controller Logic

Now that we've built our project the compiler knows about our new models for sure. Let's add a controller by right-clicking on the controller folder and selecting add > controller.

We'll choose to create an "MVC 5 Controller with views using Entity Framework", you'll see a form appear add the following constraints: 

071552d9-9f98-4712-a71a-45d9c1f73879createPagesController.PNG

We'll put our MetaViewModel to use in our new PagesController, add the following Action Result to your controller.

    
public ActionResult ListMeta(int? id = 1)
{
    var post = db.Pages.Find(id);

    MetaViewModel meta = new MetaViewModel();
    meta.Author = post.Author;
    meta.Keywords = post.Keywords;
    meta.Description = post.Description;

    return PartialView("~/Views/Pages/_ListMeta.cshtml", meta);
}

We'll need a Partial View

Notice that we're returning a partial view in this method, obviously that doesn't exist yet, so we'll need to make that now. Right click on your "ListMeta" method and select Add View. A dialog window will appear, make sure you fill it out just as I've done below.

76ed1ee5-5eba-4af3-8e87-8812e8afdbf4metaform_partial.png

Once your new partial view is created lets replace the code with the following:

    
@MetatagsExample.Models.MetaViewModel

< meta name="description" content="@Html.DisplayFor(modelItem => Model.Description)">
< meta name="keywords" content="@Html.DisplayFor(modelItem => Model.Description)">
< meta name="author" content="@Html.DisplayFor(modelItem => Model.Author)">

Lets open up our Details page for this controller by going to Views > Pages > Details.cshtml, we'll add the following lines to the top of our class (just below our @model code): 

 
    
@section metatags {
    @Html.Action("ListMeta", "Pages", new { id = Model.Id })
}

Now, lets open our _Layout.cshtml, which acts as a template for all of our future Pages and we'll add the following line inside our <head> tags:

    
@RenderSection("metatags", false)

Alright, we're ready to create our database!

Open your package manager console window by selecting view > other windows > package manager console. Once your console has opened we're going to run the following three commands individually.

  • enable-migrations
  • add-migration initial
  • update-database

If everything was successful, you now have a local database which will serve nicely for our example.

Build and Run

Finally, lets build and run our project. Once your project compiles and the browser opens. Navigate to the following URL:

localhost:{port}/pages/create

You'll see a create form, fill it out and click create. You've just created a "Page" that contains your specified meta data. After your record posts, you'll see a new screen with the results. Click the "details" link and you'll be taken to the details page.

Right-click and choose "View Source" and you should see your specified source as I've shown below

c59d96ea-e78a-4eef-8e25-f16ebd5228f2pagesource.png

That's it... If you have any problems just leave a comment and I'll try to clarify for you.