Надеюсь, это сработает или, по крайней мере, установит правильный путь. Поскольку тестирование кажется довольно сложным, я собираюсь сделать это. Если у вас есть простой тестовый код, я буду рад протестировать.
Во-первых, мне не очень нравится ваша опубликованная реализация. Вы подключаетесь к наблюдаемым объектам ItemAdded
и ItemRemoved
, вообще не используя данные; вы получаете данные из свойства Items
. Это может привести к состоянию гонки в плохой реализации, когда событие отправляется до обновления свойства. Поэтому я создал свою собственную реализацию. Я также рекомендую добавить его в метод расширения, потому что это облегчит жизнь позже:
public static IObservable<string> ToAggregatedObservable(this IItemCollection itemCollection)
{
return Observable.Merge(
itemCollection.ItemAdded.Select(item => (op: "+", item)),
itemCollection.ItemRemoved.Select(item => (op: "-", item))
)
.Scan(ImmutableList<IItem>.Empty.AddRange(itemCollection.Items), (list, t) =>
t.op == "+"
? list.Add(t.item)
: list.Remove(t.item)
)
.Select(l => l.Select(item => item.Changed).Merge())
.Switch();
}
Простите магическую строку c за секунду, вы можете превратить ее в enum
, если хотите. Мы сохраняем состояние текущих элементов в ImmutableList
внутри Scan
. Когда элемент добавляется / удаляется, мы обновляем список, а затем переключаем наблюдаемое.
Этот же лог c можно применить к уровню менеджера коллекции:
public static IObservable<string> ToAggregatedObservable(this IItemCollectionManager itemCollectionManager)
{
return Observable.Merge(
itemCollectionManager.ItemCollectionAdded.Select(itemColl => (op: "+", itemColl)),
itemCollectionManager.ItemCollectionRemoved.Select(itemColl => (op: "-", itemColl))
)
.Scan(ImmutableList<IItemCollection>.Empty.AddRange(itemCollectionManager.ItemCollectionCollection), (list, t) =>
t.op == "+"
? list.Add(t.itemColl)
: list.Remove(t.itemColl)
)
.Select(l => l.Select(itemColl => itemColl.ToAggregatedObservable()).Merge())
.Switch();
}
Здесь мы Вы просто повторно используете первый метод расширения, используя то же самое добавление / удаление, затем переключаете logi c, как и раньше.