Added ICollectionSynchronization

This commit is contained in:
TheXamlGuy
2024-06-04 12:14:00 +01:00
parent c13d565e7c
commit 2cf9a19ac7
11 changed files with 109 additions and 23 deletions
+2
View File
@@ -45,6 +45,8 @@ public class ComponentBuilder :
services.AddHandler<NavigateHandler>(); services.AddHandler<NavigateHandler>();
services.AddHandler<NavigateBackHandler>(); services.AddHandler<NavigateBackHandler>();
services.AddTransient<ICollectionSynchronizer, CollectionSynchronizer>();
}); });
} }
@@ -1,7 +1,7 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public class ValueStore<T> : public class DecoratorService<T> :
IValueStore<T> IDecoratorService<T>
{ {
public T? Value { get; private set; } public T? Value { get; private set; }
+2
View File
@@ -65,6 +65,8 @@ public class DefaultHostBuilder :
services.AddHandler<NavigateHandler>(); services.AddHandler<NavigateHandler>();
services.AddHandler<NavigateBackHandler>(); services.AddHandler<NavigateBackHandler>();
services.AddTransient<ICollectionSynchronizer, CollectionSynchronizer>();
services.AddInitializer<ComponentInitializer>(); services.AddInitializer<ComponentInitializer>();
services.AddHostedService<AppService>(); services.AddHostedService<AppService>();
}); });
@@ -1,6 +1,6 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public interface IValueStore<T> public interface IDecoratorService<T>
{ {
T? Value { get; } T? Value { get; }
+7 -2
View File
@@ -11,12 +11,17 @@ public interface IMediator
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TMessage : notnull; where TMessage : notnull;
IAsyncEnumerable<object?> HandleMany(object message, IAsyncEnumerable<object?> HandleManyAsync(object message,
object? key = null, object? key = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
IAsyncEnumerable<TResponse?> HandleMany<TMessage, TResponse>(TMessage message, IAsyncEnumerable<TResponse?> HandleManyAsync<TMessage, TResponse>(TMessage message,
object? key = null, object? key = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TMessage : notnull; where TMessage : notnull;
Task<IList<TResponse?>> HandleMany<TMessage, TResponse>(TMessage message,
object? key = null,
CancellationToken cancellationToken = default)
where TMessage : notnull;
} }
-5
View File
@@ -8,9 +8,4 @@ public interface IProvider<TParameter, TService>
public interface IProvider<TService> public interface IProvider<TService>
{ {
TService? Get(); TService? Get();
}
public interface ISelectable
{
bool Selected { get; set; }
} }
+6
View File
@@ -0,0 +1,6 @@
namespace Toolkit.Foundation;
public interface ISelectable
{
bool Selected { get; set; }
}
+29 -4
View File
@@ -53,8 +53,34 @@ public class Mediator(IHandlerProvider handlerProvider,
return default; return default;
} }
public async IAsyncEnumerable<object?> HandleMany(object message, public async Task<List<object?>> HandleMany(object message,
object? key = null, object? key = null,
CancellationToken cancellationToken = default)
{
List<object?> responses = [];
await foreach (object? response in HandleManyAsync(message, key, cancellationToken))
{
responses.Add(response);
}
return responses;
}
public async Task<IList<TResponse?>> HandleMany<TMessage, TResponse>(TMessage message,
object? key = null,
CancellationToken cancellationToken = default)
where TMessage : notnull
{
List<TResponse?> responses = [];
await foreach (TResponse? response in HandleManyAsync<TMessage, TResponse>(message, key, cancellationToken))
{
responses.Add(response);
}
return responses;
}
public async IAsyncEnumerable<object?> HandleManyAsync(object message,
object? key = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default) [EnumeratorCancellation] CancellationToken cancellationToken = default)
{ {
Type messageType = message.GetType(); Type messageType = message.GetType();
@@ -76,14 +102,12 @@ public class Mediator(IHandlerProvider handlerProvider,
} }
} }
} }
public async IAsyncEnumerable<TResponse?> HandleManyAsync<TMessage, TResponse>(TMessage message,
public async IAsyncEnumerable<TResponse?> HandleMany<TMessage, TResponse>(TMessage message,
object? key = null, object? key = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default) [EnumeratorCancellation] CancellationToken cancellationToken = default)
where TMessage : notnull where TMessage : notnull
{ {
List<object?> handlers = GetHandlers<TMessage, TResponse>(message, key); List<object?> handlers = GetHandlers<TMessage, TResponse>(message, key);
foreach (object? handler in handlers) foreach (object? handler in handlers)
{ {
MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]); MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]);
@@ -93,6 +117,7 @@ public class Mediator(IHandlerProvider handlerProvider,
} }
} }
} }
private List<object?> GetHandlers<TMessage, TResponse>(TMessage message, object? key) private List<object?> GetHandlers<TMessage, TResponse>(TMessage message, object? key)
where TMessage : notnull where TMessage : notnull
{ {
+6
View File
@@ -0,0 +1,6 @@
namespace Toolkit.Foundation;
public static class MediatorExtensions
{
}
+2 -1
View File
@@ -2,7 +2,8 @@
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] [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; public Type Type => type;
+52 -8
View File
@@ -6,6 +6,40 @@ using System.Reactive.Disposables;
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public interface IIndexable
{
int Index { get; }
}
public interface ICollectionSynchronization<TItem>
where TItem : notnull
{
int IndexOf(TItem item);
}
public interface ICollectionSynchronizer
{
void Set<TItem>(ICollectionSynchronization<TItem> collection)
where TItem : notnull;
}
public class CollectionSynchronizer(IServiceProvider serviceProvider) :
ICollectionSynchronizer
{
private readonly IServiceProvider serviceProvider = serviceProvider;
public void Set<TItem>(ICollectionSynchronization<TItem> collection)
where TItem : notnull
{
if (serviceProvider.GetService<IDecoratorService<ICollectionSynchronization<TItem>>>()
is IDecoratorService<ICollectionSynchronization<TItem>> decoratorService)
{
decoratorService.Set(collection);
}
}
}
public partial class ObservableCollection<TItem> : public partial class ObservableCollection<TItem> :
ObservableObject, ObservableObject,
IObservableCollectionViewModel<TItem>, IObservableCollectionViewModel<TItem>,
@@ -18,6 +52,7 @@ public partial class ObservableCollection<TItem> :
IList, IList,
IReadOnlyList<TItem>, IReadOnlyList<TItem>,
INotifyCollectionChanged, INotifyCollectionChanged,
ICollectionSynchronization<TItem>,
IServiceProviderRequired, IServiceProviderRequired,
IServiceFactoryRequired, IServiceFactoryRequired,
IMediatorRequired, IMediatorRequired,
@@ -31,7 +66,7 @@ public partial class ObservableCollection<TItem> :
INotificationHandler<MoveToEventArgs<TItem>>, INotificationHandler<MoveToEventArgs<TItem>>,
INotificationHandler<ReplaceEventArgs<TItem>>, INotificationHandler<ReplaceEventArgs<TItem>>,
INotificationHandler<SelectionEventArgs<TItem>> INotificationHandler<SelectionEventArgs<TItem>>
where TItem : where TItem : notnull,
IDisposable IDisposable
{ {
private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = []; private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = [];
@@ -54,13 +89,16 @@ public partial class ObservableCollection<TItem> :
[ObservableProperty] [ObservableProperty]
private TItem? selectedItem; private TItem? selectedItem;
public ObservableCollection(IServiceProvider provider, public ObservableCollection(ICollectionSynchronizer synchronizer,
IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) IDisposer disposer)
{ {
synchronizer.Set(this);
Provider = provider; Provider = provider;
Factory = factory; Factory = factory;
Mediator = mediator; Mediator = mediator;
@@ -73,7 +111,8 @@ public partial class ObservableCollection<TItem> :
collection.CollectionChanged += OnCollectionChanged; collection.CollectionChanged += OnCollectionChanged;
} }
public ObservableCollection(IServiceProvider provider, public ObservableCollection(ICollectionSynchronizer synchronizer,
IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
@@ -81,6 +120,8 @@ public partial class ObservableCollection<TItem> :
IDisposer disposer, IDisposer disposer,
IEnumerable<TItem> items) IEnumerable<TItem> items)
{ {
synchronizer.Set(this);
Provider = provider; Provider = provider;
Factory = factory; Factory = factory;
Mediator = mediator; Mediator = mediator;
@@ -623,21 +664,24 @@ public partial class ObservableCollection<TItem> :
} }
} }
public partial class ObservableCollection<TValue, TViewModel>(IServiceProvider provider, public partial class ObservableCollection<TValue, TViewModel>(ICollectionSynchronizer synchronizer,
IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, IDisposer disposer) : ObservableCollection<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer) ISubscription subscriber, IDisposer disposer) : ObservableCollection<TViewModel>(synchronizer, provider, factory, mediator, publisher, subscriber, disposer)
where TViewModel : IDisposable where TViewModel : notnull,
IDisposable
{ {
[ObservableProperty] [ObservableProperty]
private TValue? value; private TValue? value;
} }
public class ObservableCollection(IServiceProvider provider, public class ObservableCollection(ICollectionSynchronizer synchronizer,
IServiceProvider provider,
IServiceFactory factory, IServiceFactory factory,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : IDisposer disposer) :
ObservableCollection<IDisposable>(provider, factory, mediator, publisher, subscriber, disposer); ObservableCollection<IDisposable>(synchronizer, provider, factory, mediator, publisher, subscriber, disposer);