What is a good way to create an IObservable for a method?

后端 未结 5 1915
攒了一身酷
攒了一身酷 2021-02-05 11:30

Let\'s say, we have a class:

public class Foo
{
   public string Do(int param)
   {
   }
}

I\'d like to create an observable of values that are

相关标签:
5条回答
  • 2021-02-05 11:57

    Observable.Generate solves your problem, although you don't need to use the condition and the continue for your sample. This just creates and object and continually returns the result of the call to DoIt():

    Observable.Generate (
      new Foo(),
      item => true, // in your example, this never terminates
      item => item, // we don't actually do any state transitions
      item => { return item.DoIt(); }  // This is where we emit our value
      );
    

    In practice, you often do want to track some state and have some termination condition. Generate makes it easy.

    0 讨论(0)
  • 2021-02-05 11:57

    I would look at the EventAggregator model. There's a great article with sample code that shows an implementation with StructureMap.

    http://www.codeproject.com/KB/architecture/event_aggregator.aspx

    0 讨论(0)
  • 2021-02-05 12:02

    I'm assuming you control the Foo class, since you're talking about adding an event to it as one option. Since you own the class, is there any reason you can't define your own IObservable implementation for the Do method?

    public class Foo
    {
        DoObservable _doValues = new DoObservable();
    
        public IObservable<String> DoValues
        {
            return _doValues;
        }
    
        public string Do(int param)
        {
            string result;
            // whatever
            _doValues.Notify(result);
        }
    }
    
    public class DoObservable : IObservable<String>
    {
        List<IObserver<String>> _observers = new List<IObserver<String>>();
    
        public void Notify(string s)
        {
            foreach (var obs in _observers) obs.OnNext(s);
        }
    
        public IObserver<String> Subscribe(IObserver<String> observer)
        {
            _observers.Add(observer);
            return observer;
        }
    }
    

    Your class now has an Observable<String> property which provides a way to subscribe to the values returned from the Do method:

    public class StringWriter : IObserver<String>
    {
        public void OnNext(string value)
        {
            Console.WriteLine("Do returned " + value);
        }
    
        // and the other IObserver<String> methods
    }
    
    var subscriber = myFooInstance.DoValues.Subscribe(new StringWriter());
    // from now on, anytime myFooInstance.Do() is called, the value it 
    // returns will be written to the console by the StringWriter observer.
    

    I've not dabbled too much into the reactive framework, but I think this is close to how you would do this.

    0 讨论(0)
  • Generally you want to avoid using Subjects. In my experiance it is a sign you are doing something wrong. Observable.Create or perhaps Generate are normally better fits.

    I would be interested to see what you are actually trying to do to see if we can provide a better answer. Lee

    0 讨论(0)
  • 2021-02-05 12:06

    Matt's answer made me thinking about this:

    public class Foo
    {
        private readonly Subject<string> _doValues = new Subject<string>();
    
        public IObservable<string> DoValues { get { return _doValues; } }
    
        public string Do(int param)
        {
            var ret = (param * 2).ToString();
            _doValues.OnNext(ret);
            return ret;
        }
    }
    
    
    var foo = new Foo();
    foo.DoValues.Subscribe(Console.WriteLine);
    foo.Do(2);
    
    0 讨论(0)
提交回复
热议问题