James Nugent

http://jen20.com

Updating to Reactive UI 5

| Comments

Today I had to update a WPF application which is using Reactive UI. At the same time I decided to upgrade from the 4.x version of Reactive UI it was previously using to 5.2.0 which appears to be the (latest release)[https://github.com/reactiveui/ReactiveUI]. This post is just a quick note of some of the major changes (I’m pretty sure they’re already documented somewhere else as well…)

Platforms

Reactive UI 5 only targets .NET 4.5. Don’t think this is too big an issue – it does mean no Silverlight, but that’s dead anyway so who cares?

Namespaces and Abstractions

Many of the namespaces have been collapsed down into the root ReactiveUI namespace. The IOC abstraction has changed quite a bit, so if you had an adapter for something like Autofac it will likely want updating. IMutableDependencyResolver is the new interface. Personally I’m not using a container with this stuff so the new bits work without any changes.

ViewModel Property Declaration

Previously in Reactive UI 4, properties on a ViewModel were often declared like this:

1
2
3
4
5
6
7
private string _test2;

public string Test2
{
   get { return _test2; }
   set { this.RaiseAndSetIfChanged(vm => vm.Test2, value); }
}

The RaiseAndSetIfChanged method found the backing fields by the convention set in RxApp.GetFieldNameForPropertyNameFunc (which almost always needed overriding if you didn’t like Paul’s weird property naming convention with an initial cap :D). It also made tools like ReSharper mad, as it detected the private field as not being used.

This is no longer supported, the correct way to declare properties in ReactiveUI 5 is this:

1
2
3
4
5
6
7
private string _test2;

public string Test2
{
   get { return _test2; }
   set { this.RaiseAndSetIfChanged(ref _test2, value); }
}

Which is just better.

ReactiveAsyncCommand

Some of the static factory methods have been taken off ReactiveCommand, and ReactiveAsyncCommand has gone altogether. The originals are still there, in the ReactiveUI.Legacy namespace, however I don’t imagine they’ll stay around forever so converting everything from using ReactiveAsyncCommand to the new ReactiveCommand is probably a better idea than using the legacy classes.

Validation

The validation stuff has gone. It’s slated to be re-introduced at some point, but for any projects using things like ReactiveValidatedObject, the original version is (here)[https://github.com/reactiveui/ReactiveUI/blob/4.6.4/ReactiveUI/Validation.cs]. I’m not quite sure why the old ReactiveCommand made it into a legacy namespace but validation didn’t, but that’s how it is.

Scheduler Name

RxApp.DeferredScheduler has been renamed RxApp.MainThreadScheduler, which seems more descriptive.

That’s most of the big changes that I can spot (at least, they’re the things I had to change to make my old stuff work). By the look of it Reactive UI 5 is a lot cleaner than the previous version and is still under active development so hopefully we’ll see plenty more where it came from!

Catch-up Subscriptions With the Event Store

| Comments

This has been crossposted from the Event Store Blog. I’ll come back to Reactive UI soon!

We have had many questions about how to use the catch-up subscriptions in the C# Event Store Client API. In this post I’ll build out a simple example of a console application which receives a callback each time an event is written to the built-in statistics stream.

Contrary to what some have thought, catch-up subscriptions are implemented as part of the client, and have been available in the client API version 1.1.0 which has been on NuGet for some time. As we’re coming up to a big release which changes some aspects of the client API, I’ll build out this sample for both the version currently available on NuGet, and then in the next post for the version which can be built from the development branch and will shortly be available as part of version 2 of Event Store.

We’ll first take a look at using the current stable release, which is server version 1.0.1 and client API 1.1.0.

Server Setup

In order to make the server generate statistics at a rate that’s interesting to us (the default is a sample every 30 seconds), we’ll run it like this:

1
EventStore.SingleNode.exe --db .\catchupsubscriptions --stats-period-sec 2

This will set up a new database in .\catchupsubscriptions, and write an event to the statistics stream every two seconds. Since we’re not specifying an IP address to bind to, the Event Store will bind to the loopback address on the default ports of 1113 for TCP and 2113 for HTTP. Also, since we’re running a version 1 server and not specifying --run-projections, we won’t be able to use them, which is fine for our current purposes.

The statistics stream will be named $stats-127.0.0.1:2113.

Client Setup

For our client we’ll use a straightforward console application targeting .NET 4.0, remove all the unused references, and add the EventStore.Client package (version 1.1.0) from NuGet. To avoid dependency issues, the version of EventStore.Client.dll which comes in the NuGet package has the appropriate version of protobuf-net.dll ilmerged.

Note: methods used for connecting are slightly different in version 2, as we’ll see in the next post. This covers client version 1.1.0.

To start with, we’ll need to connect to the Event Store. The following code will connect to the local Event Store we just started:

1
2
var connection = EventStoreConnection.Create();
connection.Connect(new IPEndPoint(IPAddress.Loopback, 1113));

Next let’s subscribe to the statistics stream, and write a method which will make use of the information in each event to print the sequence number and event type to the console.

To subscribe, we’ll use the following method (in our Main method for now):

1
connection.SubscribeToStream("$stats-127.0.0.1:2113", false, EventAppeared, SubscriptionDropped);

The two callbacks EventAppeared and SubscriptionDropped have the following signatures:

1
2
3
4
5
6
7
private static void SubscriptionDropped(EventStoreSubscription subscription, string reason, Exception exception)
{
}

private static void EventAppeared(EventStoreSubscription subscription, ResolvedEvent resolvedEvent)
{
}

SubscriptionDropped is called in a number of circumstances:

  • if the server is stopped
  • if the client becomes disconnected from the server
  • if the client cannot service the events coming over the subscription quickly enough, and the server defensively drops it to avoid filling up buffers unnnecessarily.

However, it doesn’t have to be implemented, so we’ll leave it empty for now. In real-world applications you’ll probably want to try some reconnection strategy here.

EventAppeared is called whenever an event is received over the subscription (i.e. when it is written at the server).

Let’s add some code to our EventAppeared handler to print to the console when we receive an event:

1
2
3
4
5
private static void EventAppeared(EventStoreSubscription subscription, ResolvedEvent resolvedEvent)
{
   var receivedEvent = resolvedEvent.OriginalEvent;
   Console.WriteLine("{0:D4} - {1}", receivedEvent.EventNumber, receivedEvent.EventType);
}

Now, if we add a Console.ReadLine() to the end of our Main method to stop the program from terminating, we’ll see the sequence numbers and event types appear on the console – but from the point we subscribed onwards.

However, that wasn’t really the aim – what we wanted to do was use a catch-up subscription in order to receive previous events from some point in the stream before getting live ones over the subscription. So let’s change our subscription call:

1
connection.SubscribeToStreamFrom("$stats-127.0.0.1:2113", StreamPosition.Start, false, EventAppeared);

The extra parameter here is a nullable int which specifies the sequence number in the stream from which you want the subscription to start. In our case we want to start at the beginning of the stream, so we’ll use the constant StreamPosition.Start. Our callback signature changes slightly:

1
private static void EventAppeared(EventStoreCatchUpSubscription subscription, ResolvedEvent resolvedEvent)

However, the implementation can remain the same after making that change. Running this, we now see the sequence numbers from 0 to the current value appear very quickly (reading is fast!), and following that, new events will appear as they are written by the server.

Subscribing to All streams instead

If you need to subscribe to the $all stream instead of an individual stream, you’ll need to supply a Position instead of a sequence number. This is a pair of numbers representing the logical commit and prepare positions of the event respectively. Otherwise this is the same.

In the next post we’ll look at doing this with the changes made for 2.0.0 (it’s not actually all that different, just has a few things tidied up).

Reactive UI (Part 3) - Commands

| Comments

ReactiveUI has a pretty neat implementation of ICommand named ReactiveCommand, which takes advantage of RX underpinnings. This post modifies the little app from part 2 by adding a button and binding a command to it.

Changing the View

The change to the view consist solely of adding a new item to the StackPanel containing all the UI elements so far. That looks like this:

1
2
3
...
<Button Content="Click Me" Command="{Binding Path=ClickMe}"></Button>
...

As you can see, we’ve used a XAML binding to set the command of the button to be “ClickMe”, which should be on the DataContext. This is all we need to do here.

Changing the ViewModel

Obviously to bind to “ClickMe” from the View, we need a command with that name to exist! We can declare it as a simple public-get, private-set property on our MainWindowViewModel:

1
public ReactiveCommand ClickMe { get; private set; }

We need to actually set this somewhere – let’s do that in the constructor of our ViewModel. The constructor for ReactiveCommand is defined as:

1
2
public ReactiveCommand(IObservable<bool> canExecute = null,
   IScheduler scheduler = null, bool initialCondition = true)

For now, the first parameter is the most interesting. It’s an IObservable representing whether or not the command can be executed. Awesome, no more waiting for that to refresh and having UI out of sync with reality!

We’ll assume for now that the command can’t be executed if there is no text (or only whitespace) in the SomeText property:

1
2
3
4
5
6
7
public MainWindowViewModel()
{
   var canClickMeObservable = this.WhenAny(vm => vm.SomeText,
      s => !string.IsNullOrWhiteSpace(s.Value));

   ClickMe = new ReactiveCommand(canClickMeObservable);
}

We’ll look into the slightly odd WhenAny syntax later – for now it’s sufficient to know that the first parameters (n of them) determine the values that get passed into the lambda.

This works basically as we’d expect – the button is enabled when non-whitespace text is entered into the TextBox bound to SomeText. However, clicking the button does nothing.

It turns out, the other neat thing about ReactiveCommand is that it’s an IObservable in it’s own right! So we can subscribe to it, and we’ll get an event fired on the subscription whenever the command is executed. We’ll add a line to the constructor to subscribe, and use a ReactiveUI-provided extension method such that an Action<object> of our choosing is called whenever the command is executed:

1
2
//The viewmodel is *not* the ideal place to be doing this!
ClickMe.Subscribe(param => MessageBox.Show("I was clicked"));

The subscribe we’re using here is definied as an extension method to IObservable in ReactiveUI, and is fairly useful (we can pass in a method group, for example).

Next we’ll go back to the definition of whenAny() and figure out what’s going on.

Reactive UI (Part 2) - INotifyPropertyChanged

| Comments

One of the things that most MVVM frameworks provide is a class implementing INotifyPropertyChanged and so forth in order to allow data binding to work correctly. The ReactiveUI way of providing this is to provide a base class named ReactiveObject from which you can derive view models.

Let’s add a view model for the main window named MainWindowViewModel and then in the constructor of MainWindow (yeah, I know) set the DataContext to a new instance of that:

1
2
3
4
5
public MainWindow()
{
  InitializeComponent();
  DataContext = new MainWindowViewModel();
}

Next, in the MainWindow XAML, we’ll add a TextBlock and a TextBox, and bind them to the same as-yet non-existent property on the ViewModel, for now using the standard built-in XAML binding strings:

1
2
3
4
<StackPanel>
    <TextBlock Text="{Binding Path=SomeText, Mode=OneWay}"></TextBlock>
    <TextBox Text="{Binding Path=SomeText, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>

Now we need to add the SomeText property to the ViewModel. The ReactiveUI way to do this is to have a property and a backing field:

1
2
3
4
5
6
7
8
9
10
public class MainWindowViewModel : ReactiveObject
{
  private string _SomeText;

  public string SomeText
  {
      get { return _SomeText; }
      set { this.RaiseAndSetIfChanged(value); }
  }
}

Hackery with DotPeek (since I don’t have the source to hand) shows that the implementation of RaiseAndSetIfChanged is actually an extension method defined in the ReactiveObjectExpressionMixin class, with the following signature:

1
2
3
public static TRet RaiseAndSetIfChanged<TObj, TRet>(
   this TObj This, TRet newValue, [CallerMemberName] string propertyName = null)
      where TObj : ReactiveObject

TObj can be inferred from the type making the call (provided the this keyword is used to qualify the call), and TRet is inferred from the type of the property. The cunning part here (not unique to Reactive UI) is the use of [CallerMemberName] which is evaluated at compile time to pass the name of the property as a string (as you can see by decompiling your application). This prevents us having to use magic strings in our propertyName call, or from having to use the other overload which uses an expression tree. This overload works in WPF where we can use reflection to determine which backing field should be used. On other platforms where this isn’t possible, there’s an overload which takes a reference to the backing field which should be set.

Having put this property on the ViewModel, the app runs as expected – the value of SomeText set by typing in the TextBox is reflected in the TextBlock.

However, using RaiseAndSetIfChanged required us to declare the backing property with the name _SomeText. Personally I don’t like this convention – I’d rather the backing properties followed the normal naming convention of _someText. Fortunately this can be changed – the Intellisense says we need to replace the RxApp.GetFieldNameForPropertyNameFunc with one which will do what we want.

For now I’m going to do that in the constructor of the App class (although it probably belongs in an application bootstrapper):

1
2
3
4
5
public App()
{
  RxApp.GetFieldNameForPropertyNameFunc = s =>
      string.Format("_{0}{1}", s.Substring(0, 1).ToLowerInvariant(), s.Substring(1));
}

After this change, the field name can be changed to _someText, and all is well.

In the next post, I’m going to look at binding commands to buttons.

Reactive UI (Part 1) - Intro

| Comments

Occasionally it becomes necessary for most developers to write something with a GUI. In this particular case, we need to run software on a touch screen device with a resistive touchscreen (because of the operating environment in which everyone wears gloves, and a stylus is impractical). We also need to be able to control external hardware, primarily via serial ports).

Unfortunately this rules out pretty much every device we could find other than EPOS terminals running Windows or Linux. Since the vast majority of our infrastructure is Windows, and thanks to the lack of nice options for building Windows GUIs we settled on WPF. Consequently, I need to go about re-learning WPF (haven’t touched it for over 2 years, and it’s one of those frameworks where if you don’t use it all the time you forget it all!)

Having been bitten before by using frameworks which were either too heavy (e.g. MS Prism) or made heavy use of conventions (Caliburn.Micro, though I should point out now that this was actually through no fault of the library and they can be turned off), I’ve decided to investigate using Paul Betts’ ReactiveUI library (here on GitHub), and blog about the learning process in order that hopefully others may benefit from it!

At this stage I’m only interested in WPF, and whilst I assume that much of what I’ll look at will also apply to Silverlight and Metro apps, I’m not actually certain on that (the MS UI platforms seem to be just as fragmented as the Linux ones these days – we now, what, like 4 or 5 slightly different XAML platforms!)

ReactiveUI is a fairly small library which uses the Reactive Extensions very heavily. There are also a number of other compelling reasons to use it, one of which is the view binding syntax that removes the ridiculous XAML binding strings (e.g. {Binding Path=SomeField, Mode=OneWay}) and replaces them with programmatic binding in the code behind file. It also has a routing framework which might simplify building the kind of single-window application I’m looking at.

I’m going to start by running through some of the samples that come with ReactiveUI, noting the ReactiveUI way of doing some of the common things needed for building GUIs using the MVVM pattern, and building a tiny app using these patterns to refer back to later.

Versions

Throughout these posts, I’ll be using ReactiveUI from NuGet, version 4.6.3, unless something compelling gets released during the time I’m writing (however, version 5 looks to be some way off!).

Project setup

I’m starting with a new project using the WPF Application template in VS2012, targetting .NET 4.5, and run it through my standard crap removal process with Resharper (removing unnecessary boilerplate code such as using statements that are never used, and references which are never used).

Adding the ReactiveUI package from NuGet adds quite a few packages on which it depends, including RX itself, the XAML extensions to RX and extensions to ReactiveUI such as ReactiveUI-Xaml.

In the next post, I’m going to look at the ReactiveUI way of implementing the commonly used INotifyPropertyChanged.