Reputation: 45
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:
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?RefCount()
but it doesn't help.Upvotes: 3
Views: 1576
Reputation: 1231
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.
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.
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.
Upvotes: 2