ReactiveCommand never hooks up the event handler for the canExecute observable - system.reactive

In my test case I can verify that the event handler CollectionChanged gets hooked up correctly. This occurrs when the command is created. In my view model when I do the same thing the event handler is never hooked up. Why is this?
If I make an explicit call to Undo.CanExecute(null) in my view model it will hook up the event handler. I guess I should not have to do this and that something must be wrong with my view model code.
View Model
ActionManager = new ActionManager();
var canUndo = Observable
.FromEventPattern(e => ActionManager.CollectionChanged += e, e => ActionManager.CollectionChanged -= e)
.Select(_ => ActionManager.CanUndo)
;
Undo = ReactiveCommand.CreateAsyncTask(canUndo, UndoAsync);
Test Case
public class MiscTests
{
[Fact]
public void CanExecute()
{
var am = new ActionManager();
var canUndo = Observable
.FromEventPattern(e => am.CollectionChanged += e, e => am.CollectionChanged -= e)
.Select(_ => am.CanUndo);
var command = ReactiveCommand.Create(canUndo);
var action = new CallMethodAction(() => { }, () => { });
var canExecute = command.CanExecute(null);
canExecute.Should().BeFalse();
am.Execute(action);
canExecute = command.CanExecute(null);
canExecute.Should().BeTrue();
}
}

Don't worry, your view model code is most likely correct.
What you managed to observe is a lazy nature of Rx observables in action. Digging the source code of ReactiveCommand constructor reveals that canExecute observable you provide to CreateAsyncTask factory method is not subscribed immediately, but instead Publish is called, which returns IConnectableObservable, which is stored in a private field (this.canExecute). So, the ReactiveCommand starts to actually listen to canExecute changes, when Connect is called on this.canExecute. This happens in CanExecute(object parameter) method.
So, should you explicitly call ReactiveCommand's CanExecute in your ViewModel? No, because this should be done by your View framework when you bind your command to an actual button.

Related

Strict fake forces event subcriptions to be configured in FakeItEasy 7.0

When I am using strict fake with event handlers subscriptions, those are reported as not configured in FakeItEasy 7.0.
When fake is strict, an exception is thrown - 'Call to unconfigured method of strict fake: IFoo.add_MyEvent(value: System.EventHandler)'.
I can uncomment A.CallTo configuration. But then the test doesn't pass. Putting MustHaveHappened instead of DoesNothing brings another exception - 'Expected to find it once or more but no calls were made to the fake object'.
When I remove strict configuration and let the configuraiton commented, test passes.
How should I configure the fake as strict, but handle events in the same time?
var foo = A.Fake<IFoo>(c => c.Strict());
A.CallTo(foo).Where(call => call.Method.Name == "add_MyEvent").MustHaveHappened();
var bar = new Bar(foo);
foo.MyEvent += Raise.With(foo, new EventArgs());
Assert.That(bar.EventCalled, Is.True);
public interface IFoo
{
event EventHandler MyEvent;
}
public class Bar
{
public Bar(IFoo foo)
{
foo.MyEvent += (o, s) => { EventCalled= true;};
}
public bool EventCalled { get; private set; } = false;
}
You can do this:
var foo = A.Fake<IFoo>(c => c.Strict());
EventHandler handler = null;
A.CallTo(foo).Where(call => call.Method.Name == "add_MyEvent")
.Invokes((EventHandler value) => handler += value);
var bar = new Bar(foo);
handler?.Invoke(foo, EventArgs.Empty);
Assert.That(bar.EventCalled, Is.True);
Note that when you handle event subscription manually, you can no longer use Raise to raise the event, but you can just invoke the delegate manually.
EDIT: This workaround wasn't necessary with FakeItEasy 6.x... Looks like 7.0 introduced an unintended breaking change. I'll look into it.
EDIT2: Actually, the breaking change had been anticipated, I had just forgotten about it. The workaround I proposed is actually described in the documentation

CLSA AddChild Default values

I'm using CSLA latest release and trying to add a row with default items to the collection. What I've noticed is the default constructor of the Foo class is called instead of the AddNewCore in the FooList Class. I am unable to get the AddNewCore or the Child_Create methods to get invoked when a new row is added in a XamDataGrid row. (A row is added, but it is from the default constructor of the FooLine Class--i.e. no default values and no MarkAsChild attribute.) Here is the code snippet that is in the FooList class:
protected override FooItem AddNewCore()
{
var item = DataPortal.CreateChild<FooItem>();
MarkAsChild();
Add(item);
return base.AddNewCore();
}
protected override void Child_Create()
{
var item = DataPortal.CreateChild<FooItem>();
MarkAsChild();
Add(item);
base.Child_Create();
}
What am I doing wrong?
AddNewCore() method exists in client side CSLA class 'ExtendedBindingList' with 'void' return type and same method is exists in server side class 'ObservableBindingList' with return type 'ListClass'. So we required to call run time client side method from server side.
Please refer below code for the same.
#if SILVERLIGHT
protected override void AddNewCore()
{
var item = DataPortal.CreateChild<FooItem>();
Add(item);
}
#endif
For information: The reason the above code does not work has to do with the way WPF invokes the New method. Typically, in other frameworks it is possible to hook on to that event, intercept it, and return with default data. With WPF, it is necessary to check the RecordAdding, or RecordAdded trigger events and process the invocations by hand.
In my case, the WPF would look like:
<i:Interaction.Triggers>'
i:EventTrigger EventName="RecordAdded">
<ei:CallMethodAction TargetObject="{Binding}"
MethodName="CreateDefaultAddressValuesCommand" />
</i:EventTrigger>
In the view model:
var idx = FooInformation.FooAddressList.Count - 1;
var address = await FooAddress.CreateAsync();
FooListing.FooAddressList[idx] = address;

Why do I need to dispose of subscriptions after completion?

The Intro To RX book describes the return value on OnSubscribe as IDisposible and notes that subscriptions should be disposed of when OnError and OnCompleted are called.
An interesting thing to consider is that when a sequence completes or
errors, you should still dispose of your subscription.
From Intro to RX: Lifetime Management, OnError and OnCompleted
Why is this?
For reference, this is the class I'm currently working on. I'm probably going to submit it to code review at some point.
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
/// <summary>
/// Provides a timeout mechanism that will not timeout if it is signalled often enough
/// </summary>
internal class TrafficTimeout
{
private readonly Action onTimeout;
private object signalLock = new object();
private IObserver<Unit> signals;
/// <summary>
/// Initialises a new instance of the <see cref="TrafficTimeout"/> class.
/// </summary>
/// <param name="timeout">The duration to wait after receiving signals before timing out.</param>
/// <param name="onTimeout">The <see cref="Action"/> to perform when the the timeout duration expires.</param>
public TrafficTimeout(TimeSpan timeout, Action onTimeout)
{
// Subscribe to a throttled observable to trigger the expirey
var messageQueue = new BehaviorSubject<Unit>(Unit.Default);
IDisposable subscription = null;
subscription = messageQueue.Throttle(timeout).Subscribe(
p =>
{
messageQueue.OnCompleted();
messageQueue.Dispose();
});
this.signals = messageQueue.AsObserver();
this.onTimeout = onTimeout;
}
/// <summary>
/// Signals that traffic has been received.
/// </summary>
public void Signal()
{
lock (this.signalLock)
{
this.signals.OnNext(Unit.Default);
}
}
}
The disposable returned by the Subscribe extension methods is returned solely to allow you to manually unsubscribe from the observable before the observable naturally ends.
If the observable completes - with either OnCompleted or OnError - then the subscription is already disposed for you.
Try this code:
var xs = Observable.Create<int>(o =>
{
var d = Observable.Return(1).Subscribe(o);
return Disposable.Create(() =>
{
Console.WriteLine("Disposed!");
d.Dispose();
});
});
var subscription = xs.Subscribe(x => Console.WriteLine(x));
If you run the above you'll see that "Disposed!" is written to the console when the observable completes without you needing call .Dispose() on the subscription.
One important thing to note: the garbage collector never calls .Dispose() on observable subscriptions, so you must dispose of your subscriptions if they have not (or may not have) naturally ended before your subscription goes out of scope.
Take this, for example:
var wc = new WebClient();
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h);
var subscription =
ds.Subscribe(d =>
Console.WriteLine(d.EventArgs.Result));
The ds observable will only attach to the event handler when it has a subscription and will only detach when the observable completes or the subscription is disposed of. Since it is an event handler the observable will never complete because it is waiting for more events, and hence disposing is the only way to detach from the event (for the above example).
When you have a FromEventPattern observable that you know will only ever return one value then it is wise to add the .Take(1) extension method before subscribing to allow the event handler to automatically detach and then you don't need to manually dispose of the subscription.
Like so:
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h)
.Take(1);
I hope this helps.
Firstly, here's an example of the trouble you can run into:
void Main()
{
Console.WriteLine(GC.GetTotalMemory(true));
for (int i = 0; i < 1000; i++)
{
DumbSubscription();
Console.WriteLine(GC.GetTotalMemory(true));
}
Console.WriteLine(GC.GetTotalMemory(true));
}
public void DumbSubscription()
{
Observable.Interval(TimeSpan.FromMilliseconds(50))
.Subscribe(i => {});
}
You will see your memory usage go up forever. Active Rx subscriptions do not get garbage collected and this observable is infinite. Therefore, if you increase the loop limit, or add a delay, and you'll simply have more wasted memory: Nothing will help you except for disposing of those subscriptions.
However, let's say we change the definition of DumbSubscription to this:
public void DumbSubscription()
{
Observable.Interval(TimeSpan.FromMilliseconds(50))
.Take(1)
.Subscribe(i => {});
}
The .Take(1) addition means that the observable will complete after one interval, so it's no longer infinite. You'll see that your memory usage stabilizes: Subscriptions tend to properly dispose of themselves upon completion or exception.
However, that doesn't change the fact that, like any other IDisposable, it's a best practice to call Dispose (either manually or via using) to make sure resources are properly disposed of. Additionally, if you tweak your observable, you can easily run into the memory leak problem pointed out at the beginning.

Subscribing to a future observable

I have na event-based API (Geolocator) that I want to convert to Rx.
The problem is that some operations require that all events are unsubscribed and I don't want to pass that burdon to the user of the Rx API.
So, the user will subscribe to a few observables and when the events are subscribed they are published to those observables.
What's the best way to do this?
I thought of creating a subject that the users subscribe to and then have the events published to those through another set of observables.
Is this the best way? If so, how?
The key problem is to find a way to keep an Observer subscribed to a stream whilst tearing down and replacing an underlying source. Let's just focus on a single event source - you should be able to extrapolate from that.
First of all, here is an example class we can use that has a single event SomeEvent that follows the standard .NET pattern using an EventHandler<StringEventArgs> delegate. We will use this to create sources of events.
Note I have intercepted the event add/remove handlers in order to show you when Rx subscribes and unsubscribes from the events, and given the class a name property to let us track different instances:
public class EventSource
{
private string _sourceName;
public EventSource(string sourceName)
{
_sourceName = sourceName;
}
private event EventHandler<MessageEventArgs> _someEvent;
public event EventHandler<MessageEventArgs> SomeEvent
{
add
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Combine(_someEvent, value);
Console.WriteLine("Subscribed to SomeEvent: " + _sourceName);
}
remove
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Remove(_someEvent, value);
Console.WriteLine("Unsubscribed to SomeEvent: " + _sourceName);
}
}
public void RaiseSomeEvent(string message)
{
var temp = _someEvent;
if(temp != null)
temp(this, new MessageEventArgs(message));
}
}
public class MessageEventArgs : EventArgs
{
public MessageEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
public override string ToString()
{
return Message;
}
}
Solution Key Idea - StreamSwitcher
Now, here is the heart of the solution. We will use a Subject<IObservable<T>> to create a stream of streams. We can use the Observable.Switch() operator to return only the most recent stream to Observers. Here's the implementation, and an example of usage will follow:
public class StreamSwitcher<T> : IObservable<T>
{
private Subject<IObservable<T>> _publisher;
private IObservable<T> _stream;
public StreamSwitcher()
{
_publisher = new Subject<IObservable<T>>();
_stream = _publisher.Switch();
}
public IDisposable Subscribe(IObserver<T> observer)
{
return _stream.Subscribe(observer);
}
public void Switch(IObservable<T> newStream)
{
_publisher.OnNext(newStream);
}
public void Suspend()
{
_publisher.OnNext(Observable.Never<T>());
}
public void Stop()
{
_publisher.OnNext(Observable.Empty<T>());
_publisher.OnCompleted();
}
}
Usage
With this class you can hook up a new stream on each occasion you want to start events flowing by using the Switch method - which just sends the new event stream to the Subject.
You can unhook events using the Suspend method, which sends an Observable.Never<T>() to the Subject effectively pausing the flow of events.
Finally you can stop altogether by called to Stop to push an Observable.Empty<T>() andOnComplete()` the subject.
The best part is that this technique will cause Rx to do the right thing and properly unsubscribe from the underlying event sources each time you Switch, Suspend or Stop. Note also, that once Stopped no more events will flow, even if you Switch again.
Here's an example program:
static void Main()
{
// create the switch to operate on
// an event type of EventHandler<MessageEventArgs>()
var switcher = new StreamSwitcher<EventPattern<MessageEventArgs>>();
// You can expose switcher using Observable.AsObservable() [see MSDN]
// to hide the implementation but here I just subscribe directly to
// the OnNext and OnCompleted events.
// This is how the end user gets their uninterrupted stream:
switcher.Subscribe(
Console.WriteLine,
() => Console.WriteLine("Done!"));
// Now I'll use the example event source to wire up the underlying
// event for the first time
var source = new EventSource("A");
var sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// And we expose it to our observer with a call to Switch
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Raise some events
source.RaiseSomeEvent("1");
source.RaiseSomeEvent("2");
// When we call Suspend, the underlying event is unwired
switcher.Suspend();
Console.WriteLine("Unsubscribed");
// Just to prove it, this is not received by the observer
source.RaiseSomeEvent("3");
// Now pretend we want to start events again
// Just for kicks, we'll use an entirely new source of events
// ... but we don't have to, you could just call Switch(sourceObservable)
// with the previous instance.
source = new EventSource("B");
sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// Switch to the new event stream
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Prove it works
source.RaiseSomeEvent("3");
source.RaiseSomeEvent("4");
// Finally unsubscribe
switcher.Stop();
}
This gives output like this:
Subscribing
Subscribed to SomeEvent: A
1
2
Unsubscribed to SomeEvent: A
Unsubscribed
Subscribing
Subscribed to SomeEvent: B
3
4
Unsubscribed to SomeEvent: B
Done!
Note it doesn't matter when the end user subscribes - I did it up front, but they can Subscribe any time and they'll start getting events at that point.
Hope that helps! Of course you'll need to pull together the various event types of the Geolocator API into a single convenient wrapper - but this should enable you to get there.
If you have several events you want to combine into a single stream using this technique, look at operators like Merge, which requires you to project the source streams into a common type, with Select maybe, or something like CombineLatest - this part of the problem shouldn't be too tricky.
This is what I came up with.
I have created two subjects for the clients of my API to subscribe:
private readonly Subject<Geoposition> positionSubject = new Subject<Geoposition>();
private readonly Subject<PositionStatus> statusSubject = new Subject<PositionStatus>();
And observables for the events my API is subscribing to:
private IDisposable positionObservable;
private IDisposable statusObservable;
When I want to subscribe to the events, I just subscribe them into the subjects:
this.positionObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, PositionChangedEventArgs>, PositionChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.PositionChanged += handler,
removeHandler: handler => this.geolocator.PositionChanged -= handler)
.Select(e => e.Position)
.Subscribe(
onNext: this.positionSubject.OnNext,
onError: this.positionSubject.OnError);
this.statusObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, StatusChangedEventArgs>, StatusChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.StatusChanged += handler,
removeHandler: handler => this.geolocator.StatusChanged -= handler)
.Select(e => e.Status)
.Subscribe(
onNext: this.statusSubject.OnNext,
onError: this.statusSubject.OnError);
When I want to cancel the subscription, I just dispose of the subscriptions:
this.positionObservable.Dispose();
this.statusObservable.Dispose();

Resolving a collection of services from a service type

I have a rather complex bit of resolving going on in Autofac. Basically I want all the objects in the container which implement a specifically named method with a specific argument type. I have implemented some somewhat insane code to get it for me
var services = (from registrations in _componentContext.ComponentRegistry.Registrations
from service in registrations.Services
select service).Distinct();
foreach (var service in services.OfType<Autofac.Core.TypedService>())
{
foreach (var method in service.ServiceType.GetMethods().Where(m => m.Name == "Handle"
&& m.GetParameters().Where(p => p.ParameterType.IsAssignableFrom(implementedInterface)).Count() > 0))
{
var handler = _componentContext.Resolve(service.ServiceType);
method.Invoke(handler, new Object[] { convertedMessage });
}
}
My problem arises in that the handler returned the the resolution step is always the same handler and I cannot see a way to resolve a collection of the the registrations which are tied to the service as one might normally do with container.Resolve>().
I feel like I'm pushing pretty hard against what AutoFac was designed to do and might do better with a MEF based solution. Is there an easy AutoFac based solution to this issue or should I hop over to a more composition based approach?
G'day,
In MEF you could use 'Method Exports' for this (http://mef.codeplex.com/wikipage?title=Declaring%20Exports) but that might be a bit drastic. There are a couple of ways to achieve what you want in Autofac.
You can make the above code work by searching for registrations rather than services:
var implementorMethods = _componentContext.ComponentRegistry.Registrations
.Select(r => new {
Registration = r,
HandlerMethod = r.Services.OfType<TypedService>()
.SelectMany(ts => ts.ServiceType.GetMethods()
.Where(m => m.Name == "Handle" && ...))
.FirstOrDefault()
})
.Where(im => im.HandlerMethod != null);
foreach (var im in implementorMethods)
{
var handler = _componentContext.ResolveComponent(im.Registration, new List<Parameter>());
im.HandlerMethod.Invoke(handler, new object[] { convertedMessage });
}
I.e. implementorMethods is a list of the components implementing a handler method, along with the method itself. ResolveComponent() doesn't rely on a service to identify the implementation, so there's no problem with the service not uniquely identifying a particular implementor.
This technique in general will probably perform poorly (if perf is a concern here) but also as you suspect will work against the design goals of Autofac (and MEF,) eliminating some of the benefits.
Ideally you need to define a contract for handlers that will let you look up all handlers for a message type in a single operation.
The typical recipe looks like:
interface IHandler<TMessage>
{
void Handle(TMessage message);
}
Handlers then implement the appropriate interface:
class FooHandler : IHandler<Foo> { ... }
...and get registered at build-time like so:
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(FooHandler).Assembly)
.AsClosedTypesOf(typeof(IHandler<>));
To invoke the handlers, define a message dispatcher contract:
interface IMessageDispatcher
{
void Dispatch(object message);
}
...and then its implementation:
class AutofacMessageDispatcher : IMessageDispatcher
{
static readonly MethodInfo GenericDispatchMethod =
typeof(AutofacMessageDispatcher).GetMethod(
"GenericDispatch", BindingFlags.NonPublic | BindingFlags.Instance);
IComponentContext _cc;
public AutofacMessageDispatcher(IComponentContext cc)
{
_cc = cc;
}
public void Dispatch(object message)
{
var dispatchMethod = GenericDispatchMethod
.MakeGenericMethod(message.GetType());
dispatchMethod.Invoke(this, new[] { message });
}
void GenericDispatch<TMessage>(TMessage message)
{
var handlers = _cc.Resolve<IEnumerable<IHandler<TMessage>>>();
foreach (var handler in handlers)
handler.Handle(message);
}
}
...which is registered like so:
builder.RegisterType<AutofacMessageDispatcher>()
.As<IMessageDispatcher>();
The component that feeds in the messages will then resolve/use IMessageDispatcher to get the messages to the handlers.
var dispatcher = _cc.Resolve<IMessageDispatcher>();
dispatcher.Dispatch(message);
There are still ways to do this without the interface, but all rely on creating some kind of contract that uniquely defines handlers for a particular message (e.g. a delegate.)
In the long run the generic handler pattern will be the easiest to maintain.
Hope this helps, Nick.