Pergunta

Digamos que temos uma aula:

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

Eu gostaria de criar um observável de valores que estão sendo produzidos por Fazer método. Uma maneira de fazer isso seria criar um evento que está sendo chamado de Fazer E use Observable.Fromevent para criar o observável. Mas, de alguma forma, não me sinto bem com a criação de um evento apenas por causa da tarefa. Existe uma maneira melhor de fazer isso?

Foi útil?

Solução

A resposta de Matt me fez pensar sobre isso:

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

Outras dicas

Geralmente você deseja evitar o uso de assuntos. Na minha experiência, é um sinal de que você está fazendo algo errado. Obsertable.create ou talvez gerar são normalmente melhores ajustes.

Eu estaria interessado em ver o que você está realmente tentando fazer para ver se podemos fornecer uma resposta melhor. Lee

Suponho que você controla a classe Foo, já que está falando sobre adicionar um evento a ele como uma opção. Desde que você é dono da classe, há algum motivo para você não pode definir sua própria implementação IOBServable para o 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;
    }
}

Sua aula agora tem um Observable<String> Propriedade que fornece uma maneira de assinar os valores retornados do 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.

Não me envolvi muito na estrutura reativa, mas acho que isso está perto de como você faria isso.

Observable.Generate resolve seu problema, embora você não precise usar a condição e a continuação da sua amostra. Isso apenas cria e objeta e retorna continuamente o resultado da chamada para 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
  );

Na prática, você geralmente deseja rastrear algum estado e ter alguma condição de rescisão. Gerar facilita.

Eu olhava para o modelo EventAggreator. Há um ótimo artigo com código de amostra que mostra uma implementação no StructureMap.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top