Add contextual commands

This commit is contained in:
TheXamlGuy
2024-05-19 14:18:08 +01:00
parent 1b60711ec4
commit 41c7f71a9d
13 changed files with 107 additions and 68 deletions
+10
View File
@@ -0,0 +1,10 @@
namespace Toolkit.Foundation;
public record Aggerate<TValue, TOptions>(TOptions? Options = null) :
IAggerate
where TOptions : class
{
public object? Key { get; init; }
public AggerateMode Mode { get; init; }
}
+12
View File
@@ -0,0 +1,12 @@
namespace Toolkit.Foundation;
public record AggerateEventArgs<TValue> :
IAggerate
{
public object? Key { get; init; }
public static Aggerate<TValue, TOptions> With<TOptions>(TOptions options) where TOptions : class
{
return new Aggerate<TValue, TOptions>(options);
}
}
@@ -1,6 +1,6 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public enum EnumerateMode public enum AggerateMode
{ {
Append, Append,
Reset Reset
-10
View File
@@ -1,10 +0,0 @@
namespace Toolkit.Foundation;
public record Enumerate<TValue, TOptions>(TOptions? Options = null) :
IEnumerate
where TOptions : class
{
public object? Key { get; init; }
public EnumerateMode Mode { get; init; }
}
-12
View File
@@ -1,12 +0,0 @@
namespace Toolkit.Foundation;
public record EnumerateEventArgs<TValue> :
IEnumerate
{
public object? Key { get; init; }
public static Enumerate<TValue, TOptions> With<TOptions>(TOptions options) where TOptions : class
{
return new Enumerate<TValue, TOptions>(options);
}
}
@@ -1,6 +1,6 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public interface IEnumerate public interface IAggerate
{ {
object? Key { get; init; } object? Key { get; init; }
} }
+10 -11
View File
@@ -11,10 +11,18 @@ public interface IPublisher
void Publish<TMessage>(TMessage message, void Publish<TMessage>(TMessage message,
object key) object key)
where TMessage : notnull; where TMessage : notnull;
void Publish(object message,
Func<Func<Task>, Task> marshal,
object? key = null);
void Publish<TMessage>()
where TMessage : new();
void Publish(object message);
void PublishUI<TMessage>(TMessage message, void PublishUI<TMessage>(TMessage message,
object key) object key) where TMessage : notnull;
where TMessage : notnull;
void PublishUI<TMessage>(object key) void PublishUI<TMessage>(object key)
where TMessage : new(); where TMessage : new();
@@ -24,15 +32,6 @@ public interface IPublisher
void PublishUI(object message); void PublishUI(object message);
void Publish(object message,
Func<Func<Task>, Task> marshal,
object? key = null);
void PublishUI<TMessage>() void PublishUI<TMessage>()
where TMessage : new(); where TMessage : new();
void Publish<TMessage>()
where TMessage : new();
void Publish(object message);
} }
@@ -129,7 +129,8 @@ public static class IServiceCollectionExtensions
} }
public static IServiceCollection AddTemplate<TViewModel, TView>(this IServiceCollection services, public static IServiceCollection AddTemplate<TViewModel, TView>(this IServiceCollection services,
object? key = null, object? key = null,
ServiceLifetime serviceLifetime = ServiceLifetime.Transient,
params object[]? parameters) params object[]? parameters)
{ {
Type viewModelType = typeof(TViewModel); Type viewModelType = typeof(TViewModel);
@@ -137,15 +138,29 @@ public static class IServiceCollectionExtensions
key ??= viewModelType.Name.Replace("ViewModel", ""); key ??= viewModelType.Name.Replace("ViewModel", "");
services.AddTransient(viewModelType, provider => if (parameters is { Length: 0 })
provider.GetRequiredService<IServiceFactory>().Create<TViewModel>(parameters)!); {
services.Add(new ServiceDescriptor(viewModelType, viewModelType, serviceLifetime));
}
else
{
services.Add(new ServiceDescriptor(viewModelType, provider =>
provider.GetRequiredService<IServiceFactory>().Create<TViewModel>(parameters)!, serviceLifetime));
}
services.AddTransient(viewType); services.Add(new ServiceDescriptor(viewType, viewType, serviceLifetime));
services.AddKeyedTransient(viewModelType, key, (provider, key) => if (parameters is { Length: 0 })
provider.GetRequiredService<IServiceFactory>().Create<TViewModel>(parameters)!); {
services.Add(new ServiceDescriptor(viewModelType, key, viewModelType, serviceLifetime));
}
else
{
services.Add(new ServiceDescriptor(viewModelType, key, (provider, key) =>
provider.GetRequiredService<IServiceFactory>().Create<TViewModel>(parameters)!, serviceLifetime));
}
services.AddKeyedTransient(viewType, key); services.Add(new ServiceDescriptor(viewType, key, viewType, serviceLifetime));
services.AddTransient<IContentTemplateDescriptor>(provider => services.AddTransient<IContentTemplateDescriptor>(provider =>
new ContentTemplateDescriptor(key, viewModelType, viewType, parameters)); new ContentTemplateDescriptor(key, viewModelType, viewType, parameters));
+3
View File
@@ -4,5 +4,8 @@ public interface IServiceFactory
{ {
object Create(Type type, params object?[]? parameters); object Create(Type type, params object?[]? parameters);
TService Create<TService>(Action<TService> serviceDelegate,
params object?[]? parameters);
TService Create<TService>(params object?[]? parameters); TService Create<TService>(params object?[]? parameters);
} }
+2 -2
View File
@@ -7,7 +7,7 @@ public class NotificationAttribute(object key) : Attribute
} }
public class EnumerateAttribute(object key, public class EnumerateAttribute(object key,
EnumerateMode mode = EnumerateMode.Reset) : NotificationAttribute(key) AggerateMode mode = AggerateMode.Reset) : NotificationAttribute(key)
{ {
public EnumerateMode Mode => mode; public AggerateMode Mode => mode;
} }
+33 -21
View File
@@ -111,6 +111,12 @@ public partial class ObservableCollection<TItem> :
set => SetItem(index, value); set => SetItem(index, value);
} }
public void ResetAndAddRange(Action<ObservableCollection<TItem>> args)
{
Clear();
args.Invoke(this);
}
object? IList.this[int index] object? IList.this[int index]
{ {
get => collection[index]; get => collection[index];
@@ -130,24 +136,19 @@ public partial class ObservableCollection<TItem> :
} }
} }
public TItem Add() public TItem Add() =>
{ Add<TItem>(null, false);
TItem? item = Factory.Create<TItem>();
Add(item);
return item;
}
public TItem Add<T>(params object?[] parameters) public TItem Add<T>(params object?[] parameters)
where T : TItem where T : TItem => Add<T>(null, false, parameters);
{
T? item = Factory.Create<T>(parameters);
Add(item);
return item; public TItem Add<T>(IDisposable? owner,
} params object?[] parameters)
where T : TItem => Add<T>(owner, false, parameters);
public TItem Add<T>(bool scope = false) public TItem Add<T>(IDisposable? owner = null,
bool scope = false,
params object?[] parameters)
where T : where T :
TItem TItem
{ {
@@ -158,9 +159,20 @@ public partial class ObservableCollection<TItem> :
factory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>(); factory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
} }
T? item = factory is not null ? factory.Create<T>() : Factory.Create<T>(); T? item = factory is not null ? factory.Create<T>(parameters) : Factory.Create<T>(parameters);
Add(item); Add(item);
if (owner is not null)
{
Disposer.Add(owner, Disposable.Create(() =>
{
if (item is IRemovable)
{
Remove(item);
}
}));
}
return item; return item;
} }
@@ -238,17 +250,17 @@ public partial class ObservableCollection<TItem> :
Disposer.Dispose(this); Disposer.Dispose(this);
} }
public void Enumerate() public void Aggerate()
{ {
if (this.GetAttribute<EnumerateAttribute>() is EnumerateAttribute attribute) if (this.GetAttribute<EnumerateAttribute>() is EnumerateAttribute attribute)
{ {
if (attribute.Mode == EnumerateMode.Reset) if (attribute.Mode == AggerateMode.Reset)
{ {
Clear(); Clear();
} }
object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key; object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key;
Publisher.PublishUI(PrepareEnumeration(key)); Publisher.PublishUI(OnAggerate(key));
} }
} }
@@ -326,7 +338,7 @@ public partial class ObservableCollection<TItem> :
} }
Initialized = true; Initialized = true;
Enumerate(); Aggerate();
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -430,8 +442,8 @@ public partial class ObservableCollection<TItem> :
collection.Insert(index, item); collection.Insert(index, item);
} }
protected virtual IEnumerate PrepareEnumeration(object? key) => protected virtual IAggerate OnAggerate(object? key) =>
new EnumerateEventArgs<TItem>() with { Key = key }; new AggerateEventArgs<TItem>() with { Key = key };
protected virtual void RemoveItem(int index) => protected virtual void RemoveItem(int index) =>
collection.RemoveAt(index); collection.RemoveAt(index);
+4 -3
View File
@@ -4,13 +4,14 @@ using System.Reflection;
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public class Publisher(IHandlerProvider handlerProvider, public class Publisher(IHandlerProvider handlerProvider,
IServiceProvider provider, IServiceFactory serviceFactory,
IServiceProvider serviceProvider,
IDispatcher dispatcher) : IDispatcher dispatcher) :
IPublisher IPublisher
{ {
public void Publish<TMessage>(object key) public void Publish<TMessage>(object key)
where TMessage : new() => where TMessage : new() =>
Publish(new TMessage(), async args => await args(), key); Publish(serviceFactory.Create<TMessage>() ?? new TMessage(), async args => await args(), key);
public void Publish<TMessage>(TMessage message) public void Publish<TMessage>(TMessage message)
where TMessage : notnull => where TMessage : notnull =>
@@ -28,7 +29,7 @@ public class Publisher(IHandlerProvider handlerProvider,
Type handlerType = typeof(NotificationHandlerWrapper<>) Type handlerType = typeof(NotificationHandlerWrapper<>)
.MakeGenericType(notificationType); .MakeGenericType(notificationType);
List<object?> handlers = provider.GetServices(handlerType).ToList(); List<object?> handlers = serviceProvider.GetServices(handlerType).ToList();
foreach (object? handler in handlerProvider.Get(notificationType, key)) foreach (object? handler in handlerProvider.Get(notificationType, key))
{ {
handlers.Add(handler); handlers.Add(handler);
+9
View File
@@ -6,6 +6,15 @@ public class ServiceFactory(Func<Type, object?[]?, object> factory) :
public TService Create<TService>(params object?[]? parameters) => public TService Create<TService>(params object?[]? parameters) =>
(TService)factory(typeof(TService), parameters); (TService)factory(typeof(TService), parameters);
public TService Create<TService>(Action<TService> serviceDelegate,
params object?[]? parameters)
{
TService service = (TService)factory(typeof(TService), parameters);
serviceDelegate.Invoke(service);
return service;
}
public object Create(Type type, params object?[]? parameters) => public object Create(Type type, params object?[]? parameters) =>
factory(type, parameters); factory(type, parameters);
} }