Разделить IObservable, а затем объединить после обработки? - PullRequest
2 голосов
/ 23 января 2010

После экспериментов с IObservables я решил проверить их на обработку входящих сообщений по шине сообщений. По сути, я получаю IObservable<Request>, а Request содержит необходимые функции для ответа на ответ.

В какой-то момент во время обработки я должен десериализовать данные и преобразовать их из объекта Request в объект Command, который содержит то, что ему действительно нужно сделать. Команда не связана с запросом.

После десериализации я преобразую его в правильный ответ, однако для отправки ответа мне нужен оригинальный объект Request. Я хочу попытаться достичь этого, сохраняя высокую читабельность кода. До сих пор я использовал методы расширения и лямбда-выражения, чтобы получить следующее (где requests - это IObservable<Request>):

requestProcessor = requests
            .Deserialize<IdentityRequest>()
            .Where(idRequest => idRequest.Address != null)
            .Select(idRequest => new IdentityResponse() {Identity = identityTable[idRequest.Address.Address]})
            .Serialize()
            .Zip(requests, (response, request) => new {request = request, response = response})
            .Subscribe(data => data.request.Respond(data.response, ObjectTypes.IdentityResponse));  

Мой вопрос заключается в том, что, поскольку все команды до функции Zip требуют времени для обработки, Zip будет работать с одним и тем же объектом ввода (т. Е. С исходным вводом, а также с отдельным обработанным вводом), если есть постоянный поток сообщений. Как я могу это проверить?

Есть ли лучший способ сделать это?

1 Ответ

2 голосов
/ 23 января 2010

Я решил это удовлетворительно, но может быть лучший метод. Я создал монадоподобный тип, который состоит из двух типов: значение, которое представляет собой преобразуемые данные; и контекст, который является окружающими данными.

Это что-то вроде следующего:

 public class ComposedType<TValue, TContext>
 {
       public TValue Value { get; protected set; }
       public TContext Context { get; protected set; }

       public ComposedType(TValue value, TContext context)
       {
            Value = value;
            Context = context;
       }
  }

Я также определил неявные операторы для контекста и значения. Есть также несколько связанных методов расширения, которые позволяют преобразовывать значение из одного типа в новый тип.

Если у кого-то есть лучший метод, хотя я приветствую альтернативы, и я ненадолго оставлю этот вопрос без ответа.

...