diff --git a/Toolkit.Foundation/Aggerate.cs b/Toolkit.Foundation/Aggerate.cs new file mode 100644 index 0000000..b88032f --- /dev/null +++ b/Toolkit.Foundation/Aggerate.cs @@ -0,0 +1,10 @@ +namespace Toolkit.Foundation; + +public record Aggerate(TOptions? Options = null) : + IAggerate + where TOptions : class +{ + public object? Key { get; init; } + + public AggerateMode Mode { get; init; } +} \ No newline at end of file diff --git a/Toolkit.Foundation/AggerateEventArgs.cs b/Toolkit.Foundation/AggerateEventArgs.cs new file mode 100644 index 0000000..1693463 --- /dev/null +++ b/Toolkit.Foundation/AggerateEventArgs.cs @@ -0,0 +1,12 @@ +namespace Toolkit.Foundation; + +public record AggerateEventArgs : + IAggerate +{ + public object? Key { get; init; } + + public static Aggerate With(TOptions options) where TOptions : class + { + return new Aggerate(options); + } +} \ No newline at end of file diff --git a/Toolkit.Foundation/EnumerateMode.cs b/Toolkit.Foundation/AggerateMode.cs similarity index 69% rename from Toolkit.Foundation/EnumerateMode.cs rename to Toolkit.Foundation/AggerateMode.cs index 1827b0a..e7f4d54 100644 --- a/Toolkit.Foundation/EnumerateMode.cs +++ b/Toolkit.Foundation/AggerateMode.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public enum EnumerateMode +public enum AggerateMode { Append, Reset diff --git a/Toolkit.Foundation/Enumerate.cs b/Toolkit.Foundation/Enumerate.cs deleted file mode 100644 index 9a90559..0000000 --- a/Toolkit.Foundation/Enumerate.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Toolkit.Foundation; - -public record Enumerate(TOptions? Options = null) : - IEnumerate - where TOptions : class -{ - public object? Key { get; init; } - - public EnumerateMode Mode { get; init; } -} \ No newline at end of file diff --git a/Toolkit.Foundation/EnumerateEventArgs.cs b/Toolkit.Foundation/EnumerateEventArgs.cs deleted file mode 100644 index a4c519c..0000000 --- a/Toolkit.Foundation/EnumerateEventArgs.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Toolkit.Foundation; - -public record EnumerateEventArgs : - IEnumerate -{ - public object? Key { get; init; } - - public static Enumerate With(TOptions options) where TOptions : class - { - return new Enumerate(options); - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/IEnumerate.cs b/Toolkit.Foundation/IAggerate.cs similarity index 71% rename from Toolkit.Foundation/IEnumerate.cs rename to Toolkit.Foundation/IAggerate.cs index 8be8bac..3510f94 100644 --- a/Toolkit.Foundation/IEnumerate.cs +++ b/Toolkit.Foundation/IAggerate.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public interface IEnumerate +public interface IAggerate { object? Key { get; init; } } diff --git a/Toolkit.Foundation/IPublisher.cs b/Toolkit.Foundation/IPublisher.cs index c01d127..0a05a60 100644 --- a/Toolkit.Foundation/IPublisher.cs +++ b/Toolkit.Foundation/IPublisher.cs @@ -11,10 +11,18 @@ public interface IPublisher void Publish(TMessage message, object key) where TMessage : notnull; + + void Publish(object message, + Func, Task> marshal, + object? key = null); + + void Publish() + where TMessage : new(); + + void Publish(object message); void PublishUI(TMessage message, - object key) - where TMessage : notnull; + object key) where TMessage : notnull; void PublishUI(object key) where TMessage : new(); @@ -24,15 +32,6 @@ public interface IPublisher void PublishUI(object message); - void Publish(object message, - Func, Task> marshal, - object? key = null); - void PublishUI() where TMessage : new(); - - void Publish() - where TMessage : new(); - - void Publish(object message); } \ No newline at end of file diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index e53b5c1..370643c 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -129,7 +129,8 @@ public static class IServiceCollectionExtensions } public static IServiceCollection AddTemplate(this IServiceCollection services, - object? key = null, + object? key = null, + ServiceLifetime serviceLifetime = ServiceLifetime.Transient, params object[]? parameters) { Type viewModelType = typeof(TViewModel); @@ -137,15 +138,29 @@ public static class IServiceCollectionExtensions key ??= viewModelType.Name.Replace("ViewModel", ""); - services.AddTransient(viewModelType, provider => - provider.GetRequiredService().Create(parameters)!); + if (parameters is { Length: 0 }) + { + services.Add(new ServiceDescriptor(viewModelType, viewModelType, serviceLifetime)); + } + else + { + services.Add(new ServiceDescriptor(viewModelType, provider => + provider.GetRequiredService().Create(parameters)!, serviceLifetime)); + } - services.AddTransient(viewType); + services.Add(new ServiceDescriptor(viewType, viewType, serviceLifetime)); - services.AddKeyedTransient(viewModelType, key, (provider, key) => - provider.GetRequiredService().Create(parameters)!); + if (parameters is { Length: 0 }) + { + services.Add(new ServiceDescriptor(viewModelType, key, viewModelType, serviceLifetime)); + } + else + { + services.Add(new ServiceDescriptor(viewModelType, key, (provider, key) => + provider.GetRequiredService().Create(parameters)!, serviceLifetime)); + } - services.AddKeyedTransient(viewType, key); + services.Add(new ServiceDescriptor(viewType, key, viewType, serviceLifetime)); services.AddTransient(provider => new ContentTemplateDescriptor(key, viewModelType, viewType, parameters)); diff --git a/Toolkit.Foundation/IServiceFactory.cs b/Toolkit.Foundation/IServiceFactory.cs index c69fb20..5cf1845 100644 --- a/Toolkit.Foundation/IServiceFactory.cs +++ b/Toolkit.Foundation/IServiceFactory.cs @@ -4,5 +4,8 @@ public interface IServiceFactory { object Create(Type type, params object?[]? parameters); + TService Create(Action serviceDelegate, + params object?[]? parameters); + TService Create(params object?[]? parameters); } \ No newline at end of file diff --git a/Toolkit.Foundation/NotificationAttribute.cs b/Toolkit.Foundation/NotificationAttribute.cs index cf48a5f..50178f7 100644 --- a/Toolkit.Foundation/NotificationAttribute.cs +++ b/Toolkit.Foundation/NotificationAttribute.cs @@ -7,7 +7,7 @@ public class NotificationAttribute(object key) : Attribute } 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; } \ No newline at end of file diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index 8db9f96..9eb094a 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -111,6 +111,12 @@ public partial class ObservableCollection : set => SetItem(index, value); } + public void ResetAndAddRange(Action> args) + { + Clear(); + args.Invoke(this); + } + object? IList.this[int index] { get => collection[index]; @@ -130,24 +136,19 @@ public partial class ObservableCollection : } } - public TItem Add() - { - TItem? item = Factory.Create(); - - Add(item); - return item; - } + public TItem Add() => + Add(null, false); public TItem Add(params object?[] parameters) - where T : TItem - { - T? item = Factory.Create(parameters); - Add(item); + where T : TItem => Add(null, false, parameters); - return item; - } + public TItem Add(IDisposable? owner, + params object?[] parameters) + where T : TItem => Add(owner, false, parameters); - public TItem Add(bool scope = false) + public TItem Add(IDisposable? owner = null, + bool scope = false, + params object?[] parameters) where T : TItem { @@ -158,9 +159,20 @@ public partial class ObservableCollection : factory = serviceScope.ServiceProvider.GetRequiredService(); } - T? item = factory is not null ? factory.Create() : Factory.Create(); + T? item = factory is not null ? factory.Create(parameters) : Factory.Create(parameters); Add(item); + if (owner is not null) + { + Disposer.Add(owner, Disposable.Create(() => + { + if (item is IRemovable) + { + Remove(item); + } + })); + } + return item; } @@ -238,17 +250,17 @@ public partial class ObservableCollection : Disposer.Dispose(this); } - public void Enumerate() + public void Aggerate() { if (this.GetAttribute() is EnumerateAttribute attribute) { - if (attribute.Mode == EnumerateMode.Reset) + if (attribute.Mode == AggerateMode.Reset) { Clear(); } 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 : } Initialized = true; - Enumerate(); + Aggerate(); return Task.CompletedTask; } @@ -430,8 +442,8 @@ public partial class ObservableCollection : collection.Insert(index, item); } - protected virtual IEnumerate PrepareEnumeration(object? key) => - new EnumerateEventArgs() with { Key = key }; + protected virtual IAggerate OnAggerate(object? key) => + new AggerateEventArgs() with { Key = key }; protected virtual void RemoveItem(int index) => collection.RemoveAt(index); diff --git a/Toolkit.Foundation/Publisher.cs b/Toolkit.Foundation/Publisher.cs index cecca5c..0489146 100644 --- a/Toolkit.Foundation/Publisher.cs +++ b/Toolkit.Foundation/Publisher.cs @@ -4,13 +4,14 @@ using System.Reflection; namespace Toolkit.Foundation; public class Publisher(IHandlerProvider handlerProvider, - IServiceProvider provider, + IServiceFactory serviceFactory, + IServiceProvider serviceProvider, IDispatcher dispatcher) : IPublisher { public void Publish(object key) where TMessage : new() => - Publish(new TMessage(), async args => await args(), key); + Publish(serviceFactory.Create() ?? new TMessage(), async args => await args(), key); public void Publish(TMessage message) where TMessage : notnull => @@ -28,7 +29,7 @@ public class Publisher(IHandlerProvider handlerProvider, Type handlerType = typeof(NotificationHandlerWrapper<>) .MakeGenericType(notificationType); - List handlers = provider.GetServices(handlerType).ToList(); + List handlers = serviceProvider.GetServices(handlerType).ToList(); foreach (object? handler in handlerProvider.Get(notificationType, key)) { handlers.Add(handler); diff --git a/Toolkit.Foundation/ServiceFactory.cs b/Toolkit.Foundation/ServiceFactory.cs index d98b2bc..88cd537 100644 --- a/Toolkit.Foundation/ServiceFactory.cs +++ b/Toolkit.Foundation/ServiceFactory.cs @@ -6,6 +6,15 @@ public class ServiceFactory(Func factory) : public TService Create(params object?[]? parameters) => (TService)factory(typeof(TService), parameters); + public TService Create(Action serviceDelegate, + params object?[]? parameters) + { + TService service = (TService)factory(typeof(TService), parameters); + serviceDelegate.Invoke(service); + + return service; + } + public object Create(Type type, params object?[]? parameters) => factory(type, parameters); } \ No newline at end of file