Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You've generally got the right idea here, actually. You just need to do the actual dispatch. For this, SelectMany will help:</p> <pre><code>class Bus { Subject&lt;Command&gt; commands; Subject&lt;Invocation&gt; invocations; // TODO: Instantiate me List&lt;Func&lt;Command, bool&gt;&gt; handlerList; public Bus() { this.commands = new Subject&lt;Command&gt;(); this.invocations = new Subject&lt;Invocation&gt;(); commands.SelectMany(x =&gt; { // This FirstOrDefault() is just good ol' LINQ var passedHandler = handlerList.FirstOrDefault(handler =&gt; handler(x) == true); return passedHandler != null ? Observable.Return(new Invocation() { Command = x, Handled = true}) : Observable.Throw&lt;Invocation&gt;(new Exception("Unhandled!")); }).Multicast(invocations).Connect(); } /* ... snip ... */ } </code></pre> <p>But, to be honest, this doesn't really demonstrate the power of Rx, because it's executing the handler list synchronously. Let's make this more compelling by making this completely non-blocking.</p> <p>First, we'll change our Func prototype to be <code>Func&lt;Command, IObservable&lt;Invocation&gt;&gt;</code>. This means, a method that takes a command and produces a Future Invocation result (a-la <code>Task&lt;T&gt;</code>). Then, we can get identical behavior yet have our handlers be async via this selector (coding via TextArea ahead):</p> <pre><code>commands.SelectMany(x =&gt; handlerList.ToObservable() .Select(h =&gt; Observable.Defer(() =&gt; h(x))) .Concat() .SkipWhile(x =&gt; x.Handled == false) .TakeLast(1)) .Multicast(invocations).Connect(); </code></pre> <p>This is a pretty graduate-level use of Rx, but the idea is, for each Command, we're going to initially create a Stream of handlers and run them in order (that's what Defer + Concat does), until we find one whose Handled is true, then take the last one. </p> <p>The outer SelectMany selects a stream of Commands into a Stream of Future Results (i.e. the type is <code>IO&lt;IO&lt;Invocation&gt;&gt;</code> then flattens it, so it becomes a stream of results. </p> <p>No blocking ever, very concise, 100% testable, type-safe code that just expressed a pretty complicated idea that would've been really ugly to write imperatively. This is why Rx is cool.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload