Using Reactive Extensions, I can think of a number of ways to model an operation that has side effects / IO - say subscribe to messages from a chat room. I could either accept parameters (say the chat room), and an Observer, returning a Disposable, i.e.
Disposable SubscribeTo(string chatRoom, Observer<ChatMessage> observer)
or return an Observable given the parameters, i.e.
Observable<ChatMessage> GetObservableFor(string chatRoom)
When returning an Observable, I additionally have the choice between making it "hot" or "cold", i.e. performing the actual subscription either when my method is called or when the observable is subscribed to. In addition, I could make the observable multiplexed or not, i.e. share the same underlying subscription when there are more than one subscribers to the Observable, or initiate a new request each time it is subscribed to.
Is there a best practice approach to this using RX for operations that subscribe to an external source of events with parameters?
I agree with the other two answers. I would like to further add some clarifications:
Where
/Select
/Take
etc... operators. To do so creates a jarring experience and leads to unpredictable outcomes. This prevents safe composition, which is a corner stone of FP.IObservable<T>
. It is just a no-no. I have been using Rx for well over 3 years now and there is just no need for it. Even using the Subject implementations is a rare occurrence. As Brad said, look to Observable.Create for creating sequences.*To summarize, I suggest that you end up with an interface that looks like this:
IObservable<ChatMessage> MessagesFor(string chatRoom)
RE your question of sharing observable sequences, is very much something you need to decide based on your own requirements and architecture. Sometimes you may find that the underlying transport layers will do this for you, so there is no need to you to code it. Other times you may find that sharing a subscription means that the second+ subscribers may miss out on messages that only occur on subscription (e.g. State-Of-World). You could over come this by using a ReplaySubject as your MultiCaster. This raises other issues; are you prepared to take a possibly unbounded cost of storing ChatMessages?
*Disclosure: The link is to my own website
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With