3

For example I have api to get list of Items:

Task<ICollection<Item>> GetItemsAsync();

I want to work with Items with ObservableCache<Item, int>.

So, I created IItemsService:

IObservableCache<Item, int> Items { get; }

with an implementation:

private IObservableCache<Items, int> _items;

public IObservableCache<Items, int> Items => _items ?? (_items = Create().AsObservableCache().Publish().RefCount());

private IObservable<IChangeSet<Items, int>> Create()
{
    return ObservableChangeSet.Create<Items, int>(cache =>
    {
        var timer = Observable.Interval(TimeSpan.FromSeconds(1))
            .SelectMany(_ => _api.GetItemsAsync())
            .Retry()
            .Subscribe(matchInfos => cache.EditDiff(matchInfos, EqualityComparer<MatchInfo>.Default));

        return timer;
    }, item => item.Id);

Then I use this service in view model to show items:

_service.Connect()
    .Transform(item => new ItemViewModel(item))
    .Bind(out items)
    .Subscribe(_ => Initialized = true);

Initialized property need to show/hide loading indicator.

I have a few questions:

  1. Is this a good way?
  2. I need to show "There is no Items" when Items Count is 0 and Initialized property is true. But if server return 0 items - ObservableCache will not raise notify, so Initialized property will be false. What can I do with that?
  3. When I dispose all subscriptions, the timer doesn't stop. I use RefCount() but it doesn't help.
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I believe in terms of #2 Roland Pheasant (the author of the library) is working on a way to get those empty notifications https://stackoverflow.com/questions/54677930/tracking-the-execution-of-dynamic-data-filters-and-sorts – Glenn Watson Mar 04 '19 at 15:41

1 Answers1

2
  1. Using ObservableChangeSet.Create is a good way as it is flexible and also allows for retry / repeat logic. However Publish().RefCount() cannot work in your example as you are applying it to the cache and not to observable change set. Are you looking to lazy load the cache? If so I can update this answer with some examples.

  2. The answer from Glenn is correct. For optimisations reasons empty change notifications are suppressed in Dynamic Data. This restriction is in the process of being removed. See issue #206.

  3. There are unit tests to cover the disposal of resources created byObservableChangeSet. See ObservableChangeSetFixture.cs so I suspect the reason for the timer not being disposed is that the cache itself has not been disposed and it keeping the subscription alive.

Roland Pheasant
  • 1,161
  • 8
  • 8
  • Thank you for your answer. 1. Yes, i need a lazy load. 3. When i Subscribe to 'IObservable>' directly and then dispose subscription - timer dispose correctly. But if i add '.AsObservableCache' - timer will never be disposed. – Smirnov Denis Mar 05 '19 at 10:20