diff --git a/Toolkit.Foundation/ComponentBuilder.cs b/Toolkit.Foundation/ComponentBuilder.cs index b3dc932..3c199c8 100644 --- a/Toolkit.Foundation/ComponentBuilder.cs +++ b/Toolkit.Foundation/ComponentBuilder.cs @@ -24,8 +24,8 @@ public class ComponentBuilder : services.AddScoped(); services.AddScoped(provider => - new ServiceFactory((type, parameters) => - ActivatorUtilities.CreateInstance(provider, type, parameters!))); + new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, + parameters?.Where(x => x is not null).ToArray()!))); services.AddSingleton(); diff --git a/Toolkit.Foundation/DefaultHostBuilder.cs b/Toolkit.Foundation/DefaultHostBuilder.cs index 6318d9b..ee5c1cd 100644 --- a/Toolkit.Foundation/DefaultHostBuilder.cs +++ b/Toolkit.Foundation/DefaultHostBuilder.cs @@ -18,7 +18,8 @@ public class DefaultHostBuilder : .ConfigureServices((context, services) => { services.AddScoped(provider => - new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); + new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, + parameters?.Where(x => x is not null).ToArray()!))); services.AddSingleton(); diff --git a/Toolkit.Foundation/Observable.cs b/Toolkit.Foundation/Observable.cs index f3a7583..421c1b6 100644 --- a/Toolkit.Foundation/Observable.cs +++ b/Toolkit.Foundation/Observable.cs @@ -1,5 +1,4 @@ using CommunityToolkit.Mvvm.ComponentModel; -using System.ComponentModel; namespace Toolkit.Foundation; @@ -109,19 +108,46 @@ public partial class Observable : } } -public partial class Observable(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscription subscriber, - IDisposer disposer, - TValue? value = default) : Observable(provider, factory, mediator, publisher, subscriber, disposer) +public partial class Observable : + Observable + where TValue : notnull { [ObservableProperty] - private TValue? value = value; + private TValue? value; + + public Observable(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer, + TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + Value = value; + } + + public Observable(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + + } + + protected virtual void OnValueChanged() + { + + } + + partial void OnValueChanged(TValue? value) => OnValueChanged(); } -public partial class Observable : Observable +public partial class Observable : + Observable + where TKey : notnull + where TValue : notnull { [ObservableProperty] private TKey? key; @@ -129,23 +155,33 @@ public partial class Observable : Observable [ObservableProperty] private TValue? value; - public Observable(IServiceProvider provider, + public Observable(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, + IMediator mediator, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - TKey? key = default, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer) + TKey key, + TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer) { Key = key; Value = value; } - partial void OnValueChanged(TValue? value) => OnValueChanged(); + public Observable(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + + } protected virtual void OnValueChanged() { } + + partial void OnValueChanged(TValue? value) => OnValueChanged(); } \ No newline at end of file diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index 7c8d99a..d4bf388 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -37,8 +37,11 @@ public partial class ObservableCollection : { private readonly System.Collections.ObjectModel.ObservableCollection collection = []; + private readonly IDispatcher dispatcher; private readonly Queue pendingEvents = []; + private readonly Dictionary trackedProperties = []; + [ObservableProperty] private bool activated; @@ -46,9 +49,6 @@ public partial class ObservableCollection : [ObservableProperty] private int count; - - private readonly IDispatcher dispatcher; - [ObservableProperty] private bool initialized; @@ -194,30 +194,6 @@ public partial class ObservableCollection : } } - public void Fetch(bool reset = false) - { - if (reset) - { - Clear(); - } - - SynchronizeExpression expression = BuildAggregateExpression(); - Publisher.PublishUI(expression.Value, expression.Key); - } - - public void Fetch(Func aggregateDelegate, - bool reset = false) - { - if (reset) - { - Clear(); - } - - SynchronizeExpression expression = aggregateDelegate.Invoke(); - Publisher.PublishUI(expression.Value, expression.Key); - } - - public void Clear() { clearing = true; @@ -232,6 +208,14 @@ public partial class ObservableCollection : clearing = false; } + public void Commit() + { + foreach (object trackedProperty in trackedProperties.Values) + { + ((dynamic)trackedProperty).Commit(); + } + } + public bool Contains(TItem item) => collection.Contains(item); @@ -256,6 +240,28 @@ public partial class ObservableCollection : Disposer.Dispose(this); } + public void Fetch(bool reset = false) + { + if (reset) + { + Clear(); + } + + SynchronizeExpression expression = BuildAggregateExpression(); + Publisher.PublishUI(expression.Value, expression.Key); + } + + public void Fetch(Func aggregateDelegate, + bool reset = false) + { + if (reset) + { + Clear(); + } + + SynchronizeExpression expression = aggregateDelegate.Invoke(); + Publisher.PublishUI(expression.Value, expression.Key); + } public IEnumerator GetEnumerator() => collection.GetEnumerator(); @@ -554,6 +560,26 @@ public partial class ObservableCollection : return true; } + public void Revert() + { + foreach (object trackedProperty in trackedProperties.Values) + { + ((dynamic)trackedProperty).Revert(); + } + } + + public void Track(string propertyName, Func getter, Action setter) + { + if (!trackedProperties.ContainsKey(propertyName)) + { + T initialValue = getter(); + trackedProperties[propertyName] = new TrackedProperty(initialValue, setter, getter); + } + } + + protected virtual SynchronizeExpression BuildAggregateExpression() => + new(new SynchronizeEventArgs()); + protected virtual void ClearItems() => collection.Clear(); @@ -576,10 +602,6 @@ public partial class ObservableCollection : collection.Insert(index > Count ? Count : index, item); } - - protected virtual SynchronizeExpression BuildAggregateExpression() => - new(new SynchronizeEventArgs()); - protected virtual void RemoveItem(int index) => collection.RemoveAt(index); @@ -629,18 +651,88 @@ public partial class ObservableCollection(IServiceProvider p IServiceFactory factory, IMediator mediator, IPublisher publisher, - ISubscription subscriber, IDisposer disposer) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer) - where TViewModel : notnull, - IDisposable + ISubscription subscriber, + IDisposer disposer, + TValue value) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer) + where TViewModel : notnull, IDisposable + where TValue : notnull { [ObservableProperty] - private TValue? value; + private TValue value = value; + + protected virtual void OnValueChanged() + { + + } + + partial void OnValueChanged(TValue value) => OnValueChanged(); } -public class ObservableCollection(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscription subscriber, - IDisposer disposer) : - ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer); \ No newline at end of file +public partial class ObservableCollection : + ObservableCollection + where TViewModel : notnull, IDisposable + where TKey : notnull + where TValue : notnull + { + [ObservableProperty] + private TKey key; + + [ObservableProperty] + private TValue value; + + public ObservableCollection(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer, + TKey key, + TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + Key = key; + Value = value; + } + + public ObservableCollection(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer, + IEnumerable items, + TKey key, + TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer, items) + { + Key = key; + Value = value; + } + + protected virtual void OnValueChanged() + { + + } + + partial void OnValueChanged(TValue value) => OnValueChanged(); +} + +public class ObservableCollection : ObservableCollection +{ + public ObservableCollection(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + } + + public ObservableCollection(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscription subscriber, + IDisposer disposer, + IEnumerable items) : base(provider, factory, mediator, publisher, subscriber, disposer, items) + { + } +} \ No newline at end of file