Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[possible Bug]: ChangeAwareCache not capturing initialized data #669

Open
hutterm opened this issue Nov 30, 2022 · 2 comments
Open

[possible Bug]: ChangeAwareCache not capturing initialized data #669

hutterm opened this issue Nov 30, 2022 · 2 comments
Labels

Comments

@hutterm
Copy link
Contributor

hutterm commented Nov 30, 2022

Describe the bug 🐞

looking through the code because of something unrelated the following took me by surprise:

https://github.com/reactivemarbles/DynamicData/blob/main/src/DynamicData/Cache/ChangeAwareCache.cs#L54

initializing the ChangeAwareCache with a Dictionary and subsequently calling CaptureChanges() did not produce an initial ChangeSet!

I don't know if that might have an effect on the whole library as for example the ChangeAwareList does have code for the initial ChangeSet

Step to reproduce

just code review

Reproduction repository

https://github.com/reactivemarbles/DynamicData

Expected behavior

to send an initial ChangeSet

Screenshots 🖼️

No response

IDE

No response

Operating system

No response

Version

No response

Device

No response

DynamicData Version

No response

Additional information ℹ️

No response

@hutterm hutterm added the bug label Nov 30, 2022
@RolandPheasant
Copy link
Collaborator

That overload is intended as it is used by the source cache to ensure empty changeset when no subscribers are registered. That said it may be worth having an overload to explicitly suppress the notification when using this constructor

@hutterm
Copy link
Contributor Author

hutterm commented Nov 30, 2022

Maybe I shall explain how I got to this:
EFCore uses the ObservableHashSet and I wanted to use this with DynamicData. My first try was to use the ObservableCollectionEx.ToObservableChangeSet<TCollection,T>(...) overload, which wasn't very successful as that HashSet's change notifications don't really work for a list with order.
So I basically rewrote it to match a Set, maybe this is of use for the library, feel free to add it in:

    public static IObservable<IChangeSet<TObject,TKey>> ToObservableChangeSet<TCollection,TObject,TKey>(this TCollection source, Func<TObject,TKey> key)
        where TCollection : INotifyCollectionChanged,ISet<TObject>
    {
        if (source is null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        return Observable.Create<IChangeSet<TObject,TKey>>(
            observer =>
            {
                var data = new ChangeAwareCache<TObject, TKey>();

                foreach (var item in source) data.Add(item, key(item)); // <----- this right here is necessary, because the ChangeAwareCache ctor doesn't produce an initial ChangeSet

                if (data.Count > 0)
                {
                    observer.OnNext(data.CaptureChanges());
                }

                return source.ObserveCollectionChanges().Scan(
                    data,
                    (cache, args) =>
                    {
                        var changes = args.EventArgs;
                        if (changes.NewItems is not null)
                        {
                            foreach (var item in changes.NewItems.Cast<TObject>())
                            {
                                cache.Add(item, key(item));
                            }
                        }

                        if (changes.OldItems is not null)
                        {
                            cache.Remove(changes.OldItems.Cast<TObject>().Select(key));
                        }
                        return cache;
                    }).Select(cache => cache.CaptureChanges()).SubscribeSafe(observer);
            });
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants