Pregunta

Vamos a decir, tenemos una clase:

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

Me gustaría crear un observable de los valores que se están produciendo por Do método. Una forma de hacerlo sería crear un evento que está siendo llamado desde Do y el uso Observable.FromEvent para crear lo observable. Pero de alguna manera no me siento bien acerca de la creación de un evento sólo por el bien de la tarea. ¿Hay una mejor manera de hacerlo?

¿Fue útil?

Solución

La respuesta de Matt me hizo pensar en esto:

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);

Otros consejos

En general, usted quiere evitar el uso de los sujetos. En mi experiancia es una señal de que está haciendo algo mal. Observable.Create o tal vez generan son normalmente mejores ajustes.

Yo estaría interesado en ver lo que en realidad se está tratando de hacer para ver si podemos dar una mejor respuesta. Lee

Estoy asumiendo que el control de la clase Foo, ya que estamos hablando de añadir un evento a ella como una opción. Puesto que es el propietario de la clase, ¿hay alguna razón por la que no puede definir su propia implementación IObservable para el método 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;
    }
}

Su clase tiene ahora una propiedad Observable<String> que proporciona una forma de suscribirse a los valores devueltos por el método 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.

No he incursionó demasiado en el marco reactiva, pero creo que esto está cerca de cómo podría hacer esto.

Observable.Generate resuelve su problema, a pesar de que no es necesario utilizar la condición y la continúa para su muestra. Esto sólo crea y continuamente objeto y devuelve el resultado de la llamada a 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
  );

En la práctica, a menudo se quiere hacer un seguimiento a algún estado y tener alguna condición de terminación. Generar hace que sea fácil.

Me gustaría ver el modelo EventAggregator. Hay un gran artículo con el código de ejemplo que muestra una implementación con StructureMap.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top