title: Should I expose IObservable<T> on my interfaces?
body: <p>My colleague and I have dispute. We are writing a .NET application that processes massive amounts of data. It receives data elements, groups subsets of them them into blocks according to some criterion and processes those blocks.</p>
  
  <p>Let's say we have data items of type <code>Foo</code> arriving some source (from the network, for example) one by one. We wish to gather <strong>subsets</strong> of related objects of type <code>Foo</code>, construct an object of type <code>Bar</code> from each such subset and process objects of type <code>Bar</code>.</p>
  
  <p>One of us suggested the following design. Its main theme is exposing <code>IObservable&lt;T&gt;</code> objects directly from the interfaces of our components.</p>
  
  <pre><code>// ********* Interfaces **********
  interface IFooSource
  {
      // this is the event-stream of objects of type Foo
      IObservable&lt;Foo&gt; FooArrivals { get; }
  }
  
  interface IBarSource
  {
      // this is the event-stream of objects of type Bar
      IObservable&lt;Bar&gt; BarArrivals { get; }
  }
  
  / ********* Implementations *********
  class FooSource : IFooSource
  {
      // Here we put logic that receives Foo objects from the network and publishes them to the FooArrivals event stream.
  }
  
  class FooSubsetsToBarConverter : IBarSource
  {
      IFooSource fooSource;
  
      IObservable&lt;Bar&gt; BarArrivals
      {
          get
          {
              // Do some fancy Rx operators on fooSource.FooArrivals, like Buffer, Window, Join and others and return IObservable&lt;Bar&gt;
          }
      }
  }
  
  // this class will subscribe to the bar source and do processing
  class BarsProcessor
  {
      BarsProcessor(IBarSource barSource);
      void Subscribe(); 
  }
  
  // ******************* Main ************************
  class Program
  {
      public static void Main(string[] args)
      {
          var fooSource = FooSourceFactory.Create();
          var barsProcessor = BarsProcessorFactory.Create(fooSource) // this will create FooSubsetToBarConverter and BarsProcessor
  
          barsProcessor.Subscribe();
          fooSource.Run(); // this enters a loop of listening for Foo objects from the network and notifying about their arrival.
      }
  }
  </code></pre>
  
  <p>The other suggested another design that its main theme is using our own publisher/subscriber interfaces and using Rx inside the implementations only when needed.</p>
  
  <pre><code>//********** interfaces *********
  
  interface IPublisher&lt;T&gt;
  {
      void Subscribe(ISubscriber&lt;T&gt; subscriber);
  }
  
  interface ISubscriber&lt;T&gt;
  {
      Action&lt;T&gt; Callback { get; }
  }
  
  
  //********** implementations *********
  
  class FooSource : IPublisher&lt;Foo&gt;
  {
      public void Subscribe(ISubscriber&lt;Foo&gt; subscriber) { /* ...  */ }
  
      // here we put logic that receives Foo objects from some source (the network?) publishes them to the registered subscribers
  }
  
  class FooSubsetsToBarConverter  : ISubscriber&lt;Foo&gt;, IPublisher&lt;Bar&gt;
  {
      void Callback(Foo foo)
      {
          // here we put logic that aggregates Foo objects and publishes Bars when we have received a subset of Foos that match our criteria
          // maybe we use Rx here internally.
      }
  
      public void Subscribe(ISubscriber&lt;Bar&gt; subscriber) { /* ...  */ }
  }
  
  class BarsProcessor : ISubscriber&lt;Bar&gt;
  {
      void Callback(Bar bar)
      {
          // here we put code that processes Bar objects
      }
  }
  
  //********** program *********
  class Program
  {
      public static void Main(string[] args)
      {
          var fooSource = fooSourceFactory.Create();
          var barsProcessor = barsProcessorFactory.Create(fooSource) // this will create BarsProcessor and perform all the necessary subscriptions
  
          fooSource.Run();  // this enters a loop of listening for Foo objects from the network and notifying about their arrival.
      }
  }
  </code></pre>
  
  <p>Which one do you think is better? Exposing <code>IObservable&lt;T&gt;</code> and making our components create new event streams from Rx operators, or defining our own publisher/subscriber interfaces and using Rx internally if needed?</p>
  
  <p>Here are some things to consider about the designs:</p>
  
  <ul>
  <li><p>In the first design the consumer of our interfaces has the whole power of Rx at his/her fingertips and can perform any Rx operators. One of us claims this is an advantage and the other claims that this is a drawback.</p></li>
  <li><p>The second design allows us to use any publisher/subscriber architecture under the hood. The first design ties us to Rx.</p></li>
  <li><p>If we wish to use the power of Rx, it requires more work in the second design because we need to translate the custom publisher/subscriber implementation to Rx and back. It requires writing glue code for every class that wishes to do some event processing.</p></li>
  </ul>