diff --git a/Toolkit.Foundation/AggerateAttribute.cs b/Toolkit.Foundation/AggerateAttribute.cs index 24b5b14..f59bb94 100644 --- a/Toolkit.Foundation/AggerateAttribute.cs +++ b/Toolkit.Foundation/AggerateAttribute.cs @@ -1,7 +1,7 @@ namespace Toolkit.Foundation; -public class AggerateAttribute(object key, - AggerateMode mode = AggerateMode.Reset) : NotificationAttribute(key) +public class AggerateAttribute(Type type, object key, + AggerateMode mode = AggerateMode.Reset) : NotificationAttribute(type, key) { public AggerateMode Mode => mode; } \ No newline at end of file diff --git a/Toolkit.Foundation/AppService.cs b/Toolkit.Foundation/AppService.cs index a468121..5504039 100644 --- a/Toolkit.Foundation/AppService.cs +++ b/Toolkit.Foundation/AppService.cs @@ -13,7 +13,7 @@ public class AppService(IEnumerable initializers, await initializer.Initialize(); } - publisher.Publish(cancellationToken); + publisher.Publish(); } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/Toolkit.Foundation/HandlerProvider.cs b/Toolkit.Foundation/HandlerProvider.cs index d0f215e..68cb161 100644 --- a/Toolkit.Foundation/HandlerProvider.cs +++ b/Toolkit.Foundation/HandlerProvider.cs @@ -7,7 +7,6 @@ public class HandlerProvider(SubscriptionCollection subscriptions) : object? key = null) { string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{type}"; - var d = subscriptions; if (subscriptions.TryGetValue(subscriptionKey, out List? subscribers)) { foreach (WeakReference weakRef in subscribers.ToArray()) diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index caa5095..77b229f 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -32,7 +32,15 @@ public static class IServiceCollectionExtensions } public static IServiceCollection AddHandler(this IServiceCollection services, - ServiceLifetime lifetime = ServiceLifetime.Transient) + string key) + where THandler : IHandler + { + return AddHandler(services, ServiceLifetime.Transient, key); + } + + public static IServiceCollection AddHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient, + string? key = null) where THandler : IHandler { if (typeof(THandler).GetInterfaces() is Type[] contracts) @@ -47,14 +55,34 @@ public static class IServiceCollectionExtensions Type wrapperType = typeof(NotificationHandlerWrapper<>) .MakeGenericType(notificationType); - services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) - .MakeGenericType(notificationType), typeof(THandler), lifetime)); + if (key is not null) + { + services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) + .MakeGenericType(notificationType), key, typeof(THandler), lifetime)); + } + else + { + services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) + .MakeGenericType(notificationType), typeof(THandler), lifetime)); + } - services.Add(new ServiceDescriptor(wrapperType, provider => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(typeof(INotificationHandler<>).MakeGenericType(notificationType)), - provider.GetServices(typeof(IPipelineBehaviour<>) - .MakeGenericType(notificationType)))!, lifetime)); + + if (key is not null) + { + services.Add(new ServiceDescriptor(wrapperType, key, (provider, key) => + provider.GetService()?.Create(wrapperType, + provider.GetRequiredKeyedService(typeof(INotificationHandler<>).MakeGenericType(notificationType), key), + provider.GetServices(typeof(IPipelineBehaviour<>) + .MakeGenericType(notificationType)))!, lifetime)); + } + else + { + services.Add(new ServiceDescriptor(wrapperType, provider => + provider.GetService()?.Create(wrapperType, + provider.GetRequiredService(typeof(INotificationHandler<>).MakeGenericType(notificationType)), + provider.GetServices(typeof(IPipelineBehaviour<>) + .MakeGenericType(notificationType)))!, lifetime)); + } } if (contract.Name == typeof(IHandler<,>).Name && diff --git a/Toolkit.Foundation/NotificationAttribute.cs b/Toolkit.Foundation/NotificationAttribute.cs index 9bcc5b3..07aa058 100644 --- a/Toolkit.Foundation/NotificationAttribute.cs +++ b/Toolkit.Foundation/NotificationAttribute.cs @@ -1,7 +1,10 @@ namespace Toolkit.Foundation; -[AttributeUsage(AttributeTargets.Class, Inherited = true)] -public class NotificationAttribute(object key) : Attribute + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] +public class NotificationAttribute(Type type, object key) : Attribute { + public Type Type => type; + public object Key => key; } \ No newline at end of file diff --git a/Toolkit.Foundation/ObjectExtensions.cs b/Toolkit.Foundation/ObjectExtensions.cs index 1bd67f1..0d00c3f 100644 --- a/Toolkit.Foundation/ObjectExtensions.cs +++ b/Toolkit.Foundation/ObjectExtensions.cs @@ -22,11 +22,23 @@ public static class ObjectExtensions where TAttribute : Attribute { Type type = obj.GetType(); - if (type.GetAttribute() is TAttribute attribute) + if (type.GetCustomAttribute(true) is TAttribute attribute) { return attribute; } return null; } + + public static IEnumerable GetAttributes(this object obj) + where TAttribute : Attribute + { + Type type = obj.GetType(); + if (type.GetCustomAttributes(true) is IEnumerable attributes) + { + return attributes; + } + + return Enumerable.Empty(); + } } \ No newline at end of file diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index 493048d..987165c 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -157,6 +157,8 @@ public partial class ObservableCollection : { int index = collection.Count; InsertItem(index, item); + + UpdateSelection(item); } public void Add(object item) @@ -399,12 +401,17 @@ public partial class ObservableCollection : { T? item = Factory.Create(parameters); InsertItem(index, item); + UpdateSelection(item); return item; } - public void Insert(int index, TItem item) => + public void Insert(int index, + TItem item) + { InsertItem(index, item); + UpdateSelection(item); + } void IList.Insert(int index, object? value) @@ -412,6 +419,7 @@ public partial class ObservableCollection : if (value is TItem item) { Insert(index, item); + UpdateSelection(item); } } @@ -424,8 +432,27 @@ public partial class ObservableCollection : TItem item = this[oldIndex]; + bool moveSelection = false; + if (item is ISelectable oldSelection) + { + if (oldSelection.Selected) + { + moveSelection = true; + SelectedItem = default; + } + } + RemoveItem(oldIndex); - Insert(newIndex, item); + InsertItem(newIndex, item); + + if (moveSelection) + { + if (item is ISelectable newSelection) + { + newSelection.Selected = true; + dispatcher.Invoke(() => SelectedItem = item); + } + } return true; } @@ -535,7 +562,6 @@ public partial class ObservableCollection : } })); - UpdateSelection(item); collection.Insert(index > Count ? Count : index, item); } diff --git a/Toolkit.Foundation/Publisher.cs b/Toolkit.Foundation/Publisher.cs index d2f97b5..9047ee7 100644 --- a/Toolkit.Foundation/Publisher.cs +++ b/Toolkit.Foundation/Publisher.cs @@ -29,7 +29,9 @@ public class Publisher(IHandlerProvider handlerProvider, Type handlerType = typeof(NotificationHandlerWrapper<>) .MakeGenericType(notificationType); - List handlers = serviceProvider.GetServices(handlerType).ToList(); + List handlers = key is not null ? serviceProvider.GetKeyedServices(handlerType, key).ToList() : + serviceProvider.GetServices(handlerType).ToList(); + foreach (object? handler in handlerProvider.Get(notificationType, key)) { handlers.Add(handler); diff --git a/Toolkit.Foundation/Subscription.cs b/Toolkit.Foundation/Subscription.cs index 3517d63..9913398 100644 --- a/Toolkit.Foundation/Subscription.cs +++ b/Toolkit.Foundation/Subscription.cs @@ -9,11 +9,14 @@ public class Subscription(SubscriptionCollection subscriptions, public void Add(object subscriber) { Type handlerType = subscriber.GetType(); - object? key = GetKeyFromHandler(subscriber); + + IDictionary keys = GetKeysFromHandler(subscriber); foreach (Type interfaceType in GetHandlerInterfaces(handlerType)) { if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType) { + keys.TryGetValue(argumentType, out object? key); + string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{argumentType}"; subscriptions.AddOrUpdate(subscriptionKey, _ => new List { new(subscriber) }, (_, collection) => { @@ -29,11 +32,13 @@ public class Subscription(SubscriptionCollection subscriptions, public void Remove(object subscriber) { Type handlerType = subscriber.GetType(); - object? key = GetKeyFromHandler(subscriber); + IDictionary keys = GetKeysFromHandler(subscriber); foreach (Type interfaceType in GetHandlerInterfaces(handlerType)) { if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType) { + keys.TryGetValue(argumentType, out object? key); + string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{argumentType}"; if (subscriptions.TryGetValue(subscriptionKey, out List? subscribers)) { @@ -69,9 +74,22 @@ public class Subscription(SubscriptionCollection subscriptions, } } - private object? GetKeyFromHandler(object handler) => - handler.GetAttribute() is NotificationAttribute attribute - ? handler.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key : null; + //private object? GetKeyFromHandler(object handler) => + // handler.GetAttribute() is NotificationAttribute attribute + // ? handler.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key : null; + + private IDictionary GetKeysFromHandler(object handler) + { + Dictionary keys = []; + + foreach (NotificationAttribute attribute in handler.GetAttributes()) + { + keys.Add(attribute.Type, attribute.Key); + } + + return keys; + } + private IEnumerable GetHandlerInterfaces(Type handlerType) => handlerType.GetInterfaces().Where(interfaceType => diff --git a/Toolkit.Foundation/TypeExtensions.cs b/Toolkit.Foundation/TypeExtensions.cs deleted file mode 100644 index 791b0ae..0000000 --- a/Toolkit.Foundation/TypeExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Reflection; - -namespace Toolkit.Foundation; - -public static class TypeExtensions -{ - public static TAttribute? GetAttribute(this Type type) - where TAttribute : Attribute - { - if (type.GetCustomAttribute() is TAttribute attribute) - { - return attribute; - } - - return null; - } -} \ No newline at end of file