Skip to content

Commit d2b0517

Browse files
authored
Add and update Intellisense comments in ReactiveDomain.UI and ReactiveDomain.UI.Testing classes (#103)
* Add Intellisense comments to classes in ReactiveDomain.UI and ReactiveDomain.UI.Testing. * Minor performance improvement to Asserts: avoid creating an anonymous delegate at runtime, which is slower than specifying an expression lambda at compile time.
1 parent d6e8282 commit d2b0517

File tree

7 files changed

+418
-308
lines changed

7 files changed

+418
-308
lines changed

src/ReactiveDomain.UI.Testing/Asserts.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class Asserts
1414
/// <param name="cmd">The command whose CanExecute is to be compared</param>
1515
public static void CanExecute<TIn, TOut>(ReactiveCommand<TIn, TOut> cmd)
1616
{
17-
using (cmd.CanExecute.Replay(1).RefCount().ObserveOn(RxApp.MainThreadScheduler).Subscribe(Xunit.Assert.True)) { }
17+
using (cmd.CanExecute.Replay(1).RefCount().ObserveOn(RxApp.MainThreadScheduler).Subscribe(x => Xunit.Assert.True(x))) { }
1818
}
1919

2020
/// <summary>
@@ -25,7 +25,7 @@ public static void CanExecute<TIn, TOut>(ReactiveCommand<TIn, TOut> cmd)
2525
/// <param name="cmd">The command whose CanExecute is to be compared</param>
2626
public static void CannotExecute<TIn, TOut>(ReactiveCommand<TIn, TOut> cmd)
2727
{
28-
using (cmd.CanExecute.Replay(1).RefCount().ObserveOn(RxApp.MainThreadScheduler).Subscribe(Xunit.Assert.False)) { }
28+
using (cmd.CanExecute.Replay(1).RefCount().ObserveOn(RxApp.MainThreadScheduler).Subscribe(x => Xunit.Assert.False(x))) { }
2929
}
3030
}
3131
}

src/ReactiveDomain.UI/Bus/ReactiveTransientSubscriber.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,69 @@
88

99
namespace ReactiveDomain.UI
1010
{
11+
/// <summary>
12+
/// A <see cref="ReactiveObject"/> that implements Subscribe on the injected bus and
13+
/// that auto-unsubscribes when disposed.
14+
/// </summary>
1115
public abstract class ReactiveTransientSubscriber : ReactiveObject, IDisposable
1216
{
1317
private readonly List<IDisposable> _subscriptions = new List<IDisposable>();
1418
private readonly ISubscriber _eventSubscriber;
1519
private readonly ICommandSubscriber _commandSubscriber;
1620

21+
/// <summary>
22+
/// Creates a <see cref="ReactiveTransientSubscriber"/> with the injected dispatcher.
23+
/// </summary>
24+
/// <param name="bus">The dispatcher on which to subscribe to commands.</param>
25+
/// <exception cref="ArgumentNullException"><c>bus</c> is <c>null</c></exception>
1726
protected ReactiveTransientSubscriber(IDispatcher bus) : this((IBus)bus)
1827
{
1928
_commandSubscriber = bus ?? throw new ArgumentNullException(nameof(bus));
2029
}
2130

22-
protected ReactiveTransientSubscriber(IBus bus) : this((ISubscriber) bus) {}
31+
/// <summary>
32+
/// Creates a <see cref="ReactiveTransientSubscriber"/> with the injected bus.
33+
/// </summary>
34+
/// <param name="bus">The bus on which to subscribe to messages.</param>
35+
/// <exception cref="ArgumentNullException"><c>bus</c> is <c>null</c></exception>
36+
protected ReactiveTransientSubscriber(IBus bus) : this((ISubscriber) bus) { }
2337

38+
/// <summary>
39+
/// Creates a <see cref="ReactiveTransientSubscriber"/> with the injected bus.
40+
/// </summary>
41+
/// <param name="subscriber">The <see cref="ISubscriber"/> on which to subscribe to messages.</param>
42+
/// <exception cref="ArgumentNullException"><c>bus</c> is <c>null</c></exception>
2443
protected ReactiveTransientSubscriber(ISubscriber subscriber)
2544
{
2645
_eventSubscriber = subscriber ?? throw new ArgumentNullException(nameof(subscriber));
2746
}
2847

48+
/// <summary>
49+
/// Subscribes to messages of type T on the bus. This is typically used when subscribing to events.
50+
/// </summary>
51+
/// <typeparam name="T">The type of messages to subscribe to.</typeparam>
52+
/// <param name="handler">A handler for messages of type T.</param>
2953
protected void Subscribe<T>(IHandle<T> handler) where T : class, IMessage
3054
{
3155
_subscriptions.Add(_eventSubscriber.Subscribe<T>(handler));
3256
}
3357

58+
/// <summary>
59+
/// Subscribes to commands of type T on the bus.
60+
/// </summary>
61+
/// <typeparam name="T">The type of commands to subscribe to.</typeparam>
62+
/// <param name="handler">A handler for commands of type T.</param>
63+
/// <exception cref="ArgumentOutOfRangeException">The class has not been given an
64+
/// <see cref="IDispatcher"/> on which to subscribe to commands.</exception>
3465
protected void Subscribe<T>(IHandleCommand<T> handler) where T : Command
3566
{
3667
if (_commandSubscriber == null) throw new ArgumentOutOfRangeException(nameof(handler), @"TransientSubscriber not created with CommandBus to register on.");
3768
_subscriptions.Add(_commandSubscriber.Subscribe<T>(handler));
3869
}
3970

71+
/// <summary>
72+
/// Unsubscribes from all subscribed message types on the bus.
73+
/// </summary>
4074
public void Dispose()
4175
{
4276
Dispose(true);
@@ -47,10 +81,10 @@ protected virtual void Dispose(bool disposing)
4781
{
4882
if (_disposed)
4983
return;
50-
if (disposing){
84+
if (disposing) {
5185
_subscriptions?.ForEach(s => s.Dispose());
5286
}
53-
_disposed = true;
87+
_disposed = true;
5488
}
5589
}
5690
}

src/ReactiveDomain.UI/ReadModel/ReadModelProperty.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,24 @@
55

66
namespace ReactiveDomain.UI
77
{
8-
8+
/// <summary>
9+
/// A wrapper for an observable provider, intended for use in transient read models.
10+
/// This provider is a hot observable. Includes simple semantics for appending a new
11+
/// item to the provider. Late subscribers are automatically provided with the most
12+
/// recent value upon subscription.
13+
/// </summary>
14+
/// <typeparam name="T">The type of data for the provider.</typeparam>
915
public class ReadModelProperty<T> : IObservable<T>
1016
{
1117
private readonly List<IObserver<T>> _subscribed = new List<IObserver<T>>();
1218
private readonly IObservable<T> _observable;
19+
20+
/// <summary>
21+
/// Creates a new <see cref="ReadModelProperty{T}"/>.
22+
/// </summary>
23+
/// <param name="startValue">The provider's initial value.</param>
24+
/// <param name="publishWrapper">An optional wrapper to use when providing
25+
/// new values to subscribers.</param>
1326
public ReadModelProperty(T startValue, Action<Action> publishWrapper = null)
1427
{
1528
_lastValue = startValue;
@@ -19,12 +32,19 @@ public ReadModelProperty(T startValue, Action<Action> publishWrapper = null)
1932
_subscribed.Add(o);
2033
return () => _subscribed.Remove(o);
2134
});
22-
2335
}
2436

2537
private T _lastValue;
2638
private readonly Action<Action> _publishWrapper;
2739

40+
/// <summary>
41+
/// Append an item to the provider's stream and notifies all subscribers.
42+
/// The stream is unchanged and no notifications are made if the provided
43+
/// value is the same as the previous value.
44+
/// </summary>
45+
/// <param name="val">The value to be appended to the stream.</param>
46+
/// <param name="force">Forces notifications. If true, notifies subscribers of
47+
/// the new value even if that value is the same as the previous value.</param>
2848
public void Update(T val, bool force = false)
2949
{
3050
var noChange = (val != null && val.Equals(_lastValue)) || (val == null && _lastValue == null);
@@ -41,6 +61,14 @@ public void Update(T val, bool force = false)
4161
subscriber.OnNext(val);
4262
}
4363
}
64+
65+
/// <summary>
66+
/// Subscribes a new observer to this observable and asynchronously notifies
67+
/// that observer of the most recent value.
68+
/// </summary>
69+
/// <param name="observer">The observer to subscribe.</param>
70+
/// <returns>A reference to an interface that allows observers to stop receiving
71+
/// notifications before the provider has finished sending them.</returns>
4472
public IDisposable Subscribe(IObserver<T> observer)
4573
{
4674
var unsubscribe = _observable.Subscribe(observer);

0 commit comments

Comments
 (0)