From 2cf9a19ac7e6435541fe61e97f87f84d2cb204ca Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Tue, 4 Jun 2024 12:14:00 +0100 Subject: [PATCH] Added ICollectionSynchronization --- Toolkit.Foundation/ComponentBuilder.cs | 2 + .../{ValueStore.cs => DecoratorService.cs} | 4 +- Toolkit.Foundation/DefaultHostBuilder.cs | 2 + .../{IValueStore.cs => IDecoratorService.cs} | 2 +- Toolkit.Foundation/IMediator.cs | 9 ++- Toolkit.Foundation/IProvider.cs | 5 -- Toolkit.Foundation/ISelectable.cs | 6 ++ Toolkit.Foundation/Mediator.cs | 33 ++++++++-- Toolkit.Foundation/MediatorExtensions.cs | 6 ++ Toolkit.Foundation/NotificationAttribute.cs | 3 +- Toolkit.Foundation/ObservableCollection.cs | 60 ++++++++++++++++--- 11 files changed, 109 insertions(+), 23 deletions(-) rename Toolkit.Foundation/{ValueStore.cs => DecoratorService.cs} (67%) rename Toolkit.Foundation/{IValueStore.cs => IDecoratorService.cs} (68%) create mode 100644 Toolkit.Foundation/ISelectable.cs create mode 100644 Toolkit.Foundation/MediatorExtensions.cs diff --git a/Toolkit.Foundation/ComponentBuilder.cs b/Toolkit.Foundation/ComponentBuilder.cs index b3dc932..d1c0da8 100644 --- a/Toolkit.Foundation/ComponentBuilder.cs +++ b/Toolkit.Foundation/ComponentBuilder.cs @@ -45,6 +45,8 @@ public class ComponentBuilder : services.AddHandler(); services.AddHandler(); + + services.AddTransient(); }); } diff --git a/Toolkit.Foundation/ValueStore.cs b/Toolkit.Foundation/DecoratorService.cs similarity index 67% rename from Toolkit.Foundation/ValueStore.cs rename to Toolkit.Foundation/DecoratorService.cs index d7b3707..f3fcfb7 100644 --- a/Toolkit.Foundation/ValueStore.cs +++ b/Toolkit.Foundation/DecoratorService.cs @@ -1,7 +1,7 @@ namespace Toolkit.Foundation; -public class ValueStore : - IValueStore +public class DecoratorService : + IDecoratorService { public T? Value { get; private set; } diff --git a/Toolkit.Foundation/DefaultHostBuilder.cs b/Toolkit.Foundation/DefaultHostBuilder.cs index 6318d9b..8e50993 100644 --- a/Toolkit.Foundation/DefaultHostBuilder.cs +++ b/Toolkit.Foundation/DefaultHostBuilder.cs @@ -65,6 +65,8 @@ public class DefaultHostBuilder : services.AddHandler(); services.AddHandler(); + services.AddTransient(); + services.AddInitializer(); services.AddHostedService(); }); diff --git a/Toolkit.Foundation/IValueStore.cs b/Toolkit.Foundation/IDecoratorService.cs similarity index 68% rename from Toolkit.Foundation/IValueStore.cs rename to Toolkit.Foundation/IDecoratorService.cs index 02b1859..4205fb3 100644 --- a/Toolkit.Foundation/IValueStore.cs +++ b/Toolkit.Foundation/IDecoratorService.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public interface IValueStore +public interface IDecoratorService { T? Value { get; } diff --git a/Toolkit.Foundation/IMediator.cs b/Toolkit.Foundation/IMediator.cs index de03ff5..139a386 100644 --- a/Toolkit.Foundation/IMediator.cs +++ b/Toolkit.Foundation/IMediator.cs @@ -11,12 +11,17 @@ public interface IMediator CancellationToken cancellationToken = default) where TMessage : notnull; - IAsyncEnumerable HandleMany(object message, + IAsyncEnumerable HandleManyAsync(object message, object? key = null, CancellationToken cancellationToken = default); - IAsyncEnumerable HandleMany(TMessage message, + IAsyncEnumerable HandleManyAsync(TMessage message, object? key = null, CancellationToken cancellationToken = default) where TMessage : notnull; + + Task> HandleMany(TMessage message, + object? key = null, + CancellationToken cancellationToken = default) + where TMessage : notnull; } \ No newline at end of file diff --git a/Toolkit.Foundation/IProvider.cs b/Toolkit.Foundation/IProvider.cs index 82beb4d..ce8113b 100644 --- a/Toolkit.Foundation/IProvider.cs +++ b/Toolkit.Foundation/IProvider.cs @@ -8,9 +8,4 @@ public interface IProvider public interface IProvider { TService? Get(); -} - -public interface ISelectable -{ - bool Selected { get; set; } } \ No newline at end of file diff --git a/Toolkit.Foundation/ISelectable.cs b/Toolkit.Foundation/ISelectable.cs new file mode 100644 index 0000000..3951dfd --- /dev/null +++ b/Toolkit.Foundation/ISelectable.cs @@ -0,0 +1,6 @@ +namespace Toolkit.Foundation; + +public interface ISelectable +{ + bool Selected { get; set; } +} \ No newline at end of file diff --git a/Toolkit.Foundation/Mediator.cs b/Toolkit.Foundation/Mediator.cs index f1d64a5..f1e8a45 100644 --- a/Toolkit.Foundation/Mediator.cs +++ b/Toolkit.Foundation/Mediator.cs @@ -53,8 +53,34 @@ public class Mediator(IHandlerProvider handlerProvider, return default; } - public async IAsyncEnumerable HandleMany(object message, + public async Task> HandleMany(object message, object? key = null, + CancellationToken cancellationToken = default) + { + List responses = []; + await foreach (object? response in HandleManyAsync(message, key, cancellationToken)) + { + responses.Add(response); + } + return responses; + } + + public async Task> HandleMany(TMessage message, + object? key = null, + CancellationToken cancellationToken = default) + where TMessage : notnull + { + List responses = []; + await foreach (TResponse? response in HandleManyAsync(message, key, cancellationToken)) + { + responses.Add(response); + } + + return responses; + } + + public async IAsyncEnumerable HandleManyAsync(object message, + object? key = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) { Type messageType = message.GetType(); @@ -76,14 +102,12 @@ public class Mediator(IHandlerProvider handlerProvider, } } } - - public async IAsyncEnumerable HandleMany(TMessage message, + public async IAsyncEnumerable HandleManyAsync(TMessage message, object? key = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) where TMessage : notnull { List handlers = GetHandlers(message, key); - foreach (object? handler in handlers) { MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]); @@ -93,6 +117,7 @@ public class Mediator(IHandlerProvider handlerProvider, } } } + private List GetHandlers(TMessage message, object? key) where TMessage : notnull { diff --git a/Toolkit.Foundation/MediatorExtensions.cs b/Toolkit.Foundation/MediatorExtensions.cs new file mode 100644 index 0000000..c2b6344 --- /dev/null +++ b/Toolkit.Foundation/MediatorExtensions.cs @@ -0,0 +1,6 @@ +namespace Toolkit.Foundation; + +public static class MediatorExtensions +{ + +} diff --git a/Toolkit.Foundation/NotificationAttribute.cs b/Toolkit.Foundation/NotificationAttribute.cs index 07aa058..18a0cd6 100644 --- a/Toolkit.Foundation/NotificationAttribute.cs +++ b/Toolkit.Foundation/NotificationAttribute.cs @@ -2,7 +2,8 @@ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] -public class NotificationAttribute(Type type, object key) : Attribute +public class NotificationAttribute(Type type, + object key) : Attribute { public Type Type => type; diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index e65f0c1..a86a127 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -6,6 +6,40 @@ using System.Reactive.Disposables; namespace Toolkit.Foundation; +public interface IIndexable +{ + int Index { get; } +} + +public interface ICollectionSynchronization + where TItem : notnull +{ + int IndexOf(TItem item); +} + +public interface ICollectionSynchronizer +{ + void Set(ICollectionSynchronization collection) + where TItem : notnull; +} + +public class CollectionSynchronizer(IServiceProvider serviceProvider) : + ICollectionSynchronizer +{ + private readonly IServiceProvider serviceProvider = serviceProvider; + + public void Set(ICollectionSynchronization collection) + where TItem : notnull + { + if (serviceProvider.GetService>>() + is IDecoratorService> decoratorService) + { + decoratorService.Set(collection); + } + } +} + + public partial class ObservableCollection : ObservableObject, IObservableCollectionViewModel, @@ -18,6 +52,7 @@ public partial class ObservableCollection : IList, IReadOnlyList, INotifyCollectionChanged, + ICollectionSynchronization, IServiceProviderRequired, IServiceFactoryRequired, IMediatorRequired, @@ -31,7 +66,7 @@ public partial class ObservableCollection : INotificationHandler>, INotificationHandler>, INotificationHandler> - where TItem : + where TItem : notnull, IDisposable { private readonly System.Collections.ObjectModel.ObservableCollection collection = []; @@ -54,13 +89,16 @@ public partial class ObservableCollection : [ObservableProperty] private TItem? selectedItem; - public ObservableCollection(IServiceProvider provider, + public ObservableCollection(ICollectionSynchronizer synchronizer, + IServiceProvider provider, IServiceFactory factory, IMediator mediator, IPublisher publisher, ISubscription subscriber, IDisposer disposer) { + synchronizer.Set(this); + Provider = provider; Factory = factory; Mediator = mediator; @@ -73,7 +111,8 @@ public partial class ObservableCollection : collection.CollectionChanged += OnCollectionChanged; } - public ObservableCollection(IServiceProvider provider, + public ObservableCollection(ICollectionSynchronizer synchronizer, + IServiceProvider provider, IServiceFactory factory, IMediator mediator, IPublisher publisher, @@ -81,6 +120,8 @@ public partial class ObservableCollection : IDisposer disposer, IEnumerable items) { + synchronizer.Set(this); + Provider = provider; Factory = factory; Mediator = mediator; @@ -623,21 +664,24 @@ public partial class ObservableCollection : } } -public partial class ObservableCollection(IServiceProvider provider, +public partial class ObservableCollection(ICollectionSynchronizer synchronizer, + IServiceProvider provider, IServiceFactory factory, IMediator mediator, IPublisher publisher, - ISubscription subscriber, IDisposer disposer) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer) - where TViewModel : IDisposable + ISubscription subscriber, IDisposer disposer) : ObservableCollection(synchronizer, provider, factory, mediator, publisher, subscriber, disposer) + where TViewModel : notnull, + IDisposable { [ObservableProperty] private TValue? value; } -public class ObservableCollection(IServiceProvider provider, +public class ObservableCollection(ICollectionSynchronizer synchronizer, + 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 + ObservableCollection(synchronizer, provider, factory, mediator, publisher, subscriber, disposer); \ No newline at end of file