0

How do I aggregate hot observables which may or may not have subscribers into a new observable and continue to provide all new data to existing subscribers?

As an example, imagine we have some class like this:


class SomeClass
{

  IObservable<string> Actions { get; set; } = Observable.Empty<string>();

  void AddActionCreator(IObservable<string> creator)
  {
    Actions = Actions.Merge(creator);
  }
}

The problem I am running into is if AddActionCreator adds a new stream of actions then any previous subscribers of SomeClass.Actions which subscribed before that new stream is merged will never get the new actions.

1 Answers1

3

It's easy to do what you want. What you need here is a SelectMany and a Subject<IObservabe<string>>.

Here's the class you need:

public class SomeClass
{
    private Subject<IObservable<string>> _sources = new Subject<System.IObservable<string>>();
    public IObservable<string> Actions { get; private set; } = null;

    public SomeClass()
    {
        this.Actions = _sources.SelectMany(x => x);
    }

    public void AddActionCreator(IObservable<string> creator)
    {
        _sources.OnNext(creator);
    }
}

Now you can use it like this:

var sc = new SomeClass();
sc.Actions.Subscribe(x => Console.WriteLine($"1:{x}"));
sc.AddActionCreator(Observable.Return("Hello"));
sc.Actions.Subscribe(x => Console.WriteLine($"2:{x}"));
sc.AddActionCreator(Observable.Range(0, 3).Select(x => $"{x}"));
sc.Actions.Subscribe(x => Console.WriteLine($"3:{x}"));
sc.AddActionCreator(Observable.Return("World"));

You'll get this output:

1:Hello
1:0
1:1
1:2
2:0
2:1
2:2
1:World
2:World
3:World

You can see that the new observables are added to the existing subscribers.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172