This commit is contained in:
TheXamlGuy
2024-05-31 14:07:35 +01:00
parent 041dd81717
commit 8f1a3252c6
10 changed files with 112 additions and 41 deletions
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -13,7 +13,7 @@ public class AppService(IEnumerable<IInitializer> initializers,
await initializer.Initialize();
}
publisher.Publish<StartedEventArgs>(cancellationToken);
publisher.Publish<StartedEventArgs>();
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
-1
View File
@@ -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<WeakReference>? subscribers))
{
foreach (WeakReference weakRef in subscribers.ToArray())
@@ -32,7 +32,15 @@ public static class IServiceCollectionExtensions
}
public static IServiceCollection AddHandler<THandler>(this IServiceCollection services,
ServiceLifetime lifetime = ServiceLifetime.Transient)
string key)
where THandler : IHandler
{
return AddHandler<THandler>(services, ServiceLifetime.Transient, key);
}
public static IServiceCollection AddHandler<THandler>(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<IServiceFactory>()?.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<IServiceFactory>()?.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<IServiceFactory>()?.Create(wrapperType,
provider.GetRequiredService(typeof(INotificationHandler<>).MakeGenericType(notificationType)),
provider.GetServices(typeof(IPipelineBehaviour<>)
.MakeGenericType(notificationType)))!, lifetime));
}
}
if (contract.Name == typeof(IHandler<,>).Name &&
+5 -2
View File
@@ -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;
}
+13 -1
View File
@@ -22,11 +22,23 @@ public static class ObjectExtensions
where TAttribute : Attribute
{
Type type = obj.GetType();
if (type.GetAttribute<TAttribute>() is TAttribute attribute)
if (type.GetCustomAttribute<TAttribute>(true) is TAttribute attribute)
{
return attribute;
}
return null;
}
public static IEnumerable<TAttribute> GetAttributes<TAttribute>(this object obj)
where TAttribute : Attribute
{
Type type = obj.GetType();
if (type.GetCustomAttributes<TAttribute>(true) is IEnumerable<TAttribute> attributes)
{
return attributes;
}
return Enumerable.Empty<TAttribute>();
}
}
+29 -3
View File
@@ -157,6 +157,8 @@ public partial class ObservableCollection<TItem> :
{
int index = collection.Count;
InsertItem(index, item);
UpdateSelection(item);
}
public void Add(object item)
@@ -399,12 +401,17 @@ public partial class ObservableCollection<TItem> :
{
T? item = Factory.Create<T>(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<TItem> :
if (value is TItem item)
{
Insert(index, item);
UpdateSelection(item);
}
}
@@ -424,8 +432,27 @@ public partial class ObservableCollection<TItem> :
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<TItem> :
}
}));
UpdateSelection(item);
collection.Insert(index > Count ? Count : index, item);
}
+3 -1
View File
@@ -29,7 +29,9 @@ public class Publisher(IHandlerProvider handlerProvider,
Type handlerType = typeof(NotificationHandlerWrapper<>)
.MakeGenericType(notificationType);
List<object?> handlers = serviceProvider.GetServices(handlerType).ToList();
List<object?> 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);
+23 -5
View File
@@ -9,11 +9,14 @@ public class Subscription(SubscriptionCollection subscriptions,
public void Add(object subscriber)
{
Type handlerType = subscriber.GetType();
object? key = GetKeyFromHandler(subscriber);
IDictionary<Type, object> 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<WeakReference> { 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<Type, object> 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<WeakReference>? subscribers))
{
@@ -69,9 +74,22 @@ public class Subscription(SubscriptionCollection subscriptions,
}
}
private object? GetKeyFromHandler(object handler) =>
handler.GetAttribute<NotificationAttribute>() is NotificationAttribute attribute
? handler.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key : null;
//private object? GetKeyFromHandler(object handler) =>
// handler.GetAttribute<NotificationAttribute>() is NotificationAttribute attribute
// ? handler.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key : null;
private IDictionary<Type, object> GetKeysFromHandler(object handler)
{
Dictionary<Type, object> keys = [];
foreach (NotificationAttribute attribute in handler.GetAttributes<NotificationAttribute>())
{
keys.Add(attribute.Type, attribute.Key);
}
return keys;
}
private IEnumerable<Type> GetHandlerInterfaces(Type handlerType) =>
handlerType.GetInterfaces().Where(interfaceType =>
-17
View File
@@ -1,17 +0,0 @@
using System.Reflection;
namespace Toolkit.Foundation;
public static class TypeExtensions
{
public static TAttribute? GetAttribute<TAttribute>(this Type type)
where TAttribute : Attribute
{
if (type.GetCustomAttribute<TAttribute>() is TAttribute attribute)
{
return attribute;
}
return null;
}
}