Что такое хороший способ создания метода IObservable для метода?
Скажем, мы имеем класс:
public class Foo
{
public string Do(int param)
{
}
}
Я хотел бы создать наблюдаемые значения, которые создаются методом Do. Один из способов сделать это - создать событие, которое вызывается из Do, и использовать Observable.FromEvent для создания наблюдаемого. Но почему-то я не чувствую себя хорошо в создании мероприятия только ради задачи. Есть ли лучший способ сделать это?
Ответы
Ответ 1
Ответ Мэт заставил меня задуматься об этом:
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);
Ответ 2
Я предполагаю, что вы контролируете класс Foo, так как вы говорите о добавлении к нему события как одного из параметров. Поскольку у вас есть класс, есть ли причина, по которой вы не можете определить свою собственную реализацию IObservable для метода Do?
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;
}
}
Теперь у вашего класса есть свойство Observable<String>
, которое предоставляет способ подписаться на значения, возвращаемые методом Do:
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.
Я не слишком много вникал в реактивную структуру, но я думаю, что это близко к тому, как вы это сделаете.
Ответ 3
Как правило, вы хотите избежать использования объектов. В моем опыте это признак того, что вы делаете что-то неправильно. Observable.Create или возможно Generate обычно лучше подходят.
Мне было бы интересно посмотреть, что вы на самом деле пытаетесь сделать, чтобы узнать, можем ли мы дать лучший ответ.
Ли
Ответ 4
Observable.Generate решает вашу проблему, хотя вам не нужно использовать условие и продолжить для своего образца. Это просто создает и объект и постоянно возвращает результат вызова 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
);
На практике вы часто хотите отслеживать состояние и иметь какое-то условие завершения. Сгенерировать облегчает.
Ответ 5
Я бы посмотрел на модель EventAggregator. Там хорошая статья с образцом кода, который показывает реализацию с StructureMap.
http://www.codeproject.com/KB/architecture/event_aggregator.aspx