wip
This commit is contained in:
@@ -19,7 +19,7 @@ public class ContentControlHandler :
|
|||||||
control.Loaded -= HandleLoaded;
|
control.Loaded -= HandleLoaded;
|
||||||
if (control.DataContext is object content)
|
if (control.DataContext is object content)
|
||||||
{
|
{
|
||||||
if (content is IInitializer initializer)
|
if (content is IInitialization initializer)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class ContentDialogHandler(IDispatcher dispatcher) :
|
|||||||
|
|
||||||
// A hack to wait for the dialog to finish loading up to make it appear more responsive
|
// A hack to wait for the dialog to finish loading up to make it appear more responsive
|
||||||
await Task.Delay(250);
|
await Task.Delay(250);
|
||||||
if (content is IInitializer initializer)
|
if (content is IInitialization initializer)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ public class ContentTemplate :
|
|||||||
{
|
{
|
||||||
if (observableViewModel.Provider is IServiceProvider provider)
|
if (observableViewModel.Provider is IServiceProvider provider)
|
||||||
{
|
{
|
||||||
IContentTemplateDescriptorProvider? contentTemplateProvider = provider.GetService<IContentTemplateDescriptorProvider>();
|
Type itemType = item.GetType();
|
||||||
INavigationRegion? viewModelContentBinder = provider.GetService<INavigationRegion>();
|
|
||||||
|
|
||||||
if (contentTemplateProvider?.Get(item.GetType().Name) is IContentTemplateDescriptor descriptor)
|
if (provider.GetRequiredKeyedService<IContentTemplateDescriptor>(itemType.Name.Replace("ViewModel", ""))
|
||||||
|
is IContentTemplateDescriptor descriptor)
|
||||||
{
|
{
|
||||||
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key) is Control control)
|
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key) is Control control)
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@ public class ContentTemplate :
|
|||||||
control.Loaded -= HandleLoaded;
|
control.Loaded -= HandleLoaded;
|
||||||
if (control.DataContext is object content)
|
if (control.DataContext is object content)
|
||||||
{
|
{
|
||||||
if (content is IInitializer initializer)
|
if (content is IInitialization initializer)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class FrameHandler :
|
|||||||
sender.AddHandler(Frame.NavigatingFromEvent, HandleNavigatingFrom);
|
sender.AddHandler(Frame.NavigatingFromEvent, HandleNavigatingFrom);
|
||||||
if (sender.DataContext is object content)
|
if (sender.DataContext is object content)
|
||||||
{
|
{
|
||||||
if (content is IInitializer initializer)
|
if (content is IInitialization initializer)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Avalonia.Controls.ApplicationLifetimes;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Toolkit.Foundation;
|
using Toolkit.Foundation;
|
||||||
|
using Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
namespace Toolkit.Avalonia;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
@@ -128,11 +129,11 @@ public static class IServiceCollectionExtensions
|
|||||||
services.AddTransient<IContentTemplate, ContentTemplate>();
|
services.AddTransient<IContentTemplate, ContentTemplate>();
|
||||||
services.AddTransient<INavigationRegion, NavigationRegion>();
|
services.AddTransient<INavigationRegion, NavigationRegion>();
|
||||||
|
|
||||||
services.AddNavigateHandler<ClassicDesktopStyleApplicationHandler>();
|
services.AddHandler<ClassicDesktopStyleApplicationHandler>(nameof(IClassicDesktopStyleApplicationLifetime));
|
||||||
services.AddNavigateHandler<SingleViewApplicationHandler>();
|
services.AddHandler<SingleViewApplicationHandler>(nameof(ISingleViewApplicationLifetime));
|
||||||
services.AddNavigateHandler<ContentControlHandler>();
|
services.AddHandler<ContentControlHandler>(nameof(ContentControl));
|
||||||
services.AddNavigateHandler<FrameHandler>();
|
services.AddHandler<FrameHandler>(nameof(Frame));
|
||||||
services.AddNavigateHandler<ContentDialogHandler>();
|
services.AddHandler<ContentDialogHandler>(nameof(ContentDialog));
|
||||||
|
|
||||||
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>(provider => new NavigationRegionCollection
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>(provider => new NavigationRegionCollection
|
||||||
{
|
{
|
||||||
@@ -144,15 +145,13 @@ public static class IServiceCollectionExtensions
|
|||||||
new ProxyServiceCollection<IComponentBuilder>(services =>
|
new ProxyServiceCollection<IComponentBuilder>(services =>
|
||||||
{
|
{
|
||||||
services.AddSingleton(provider.GetRequiredService<IDispatcher>());
|
services.AddSingleton(provider.GetRequiredService<IDispatcher>());
|
||||||
|
|
||||||
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
|
|
||||||
services.AddTransient<IContentTemplate, ContentTemplate>();
|
services.AddTransient<IContentTemplate, ContentTemplate>();
|
||||||
|
|
||||||
services.AddTransient<INavigationRegion, NavigationRegion>();
|
services.AddTransient<INavigationRegion, NavigationRegion>();
|
||||||
|
|
||||||
services.AddNavigateHandler<ContentControlHandler>();
|
services.AddHandler<ContentControlHandler>(nameof(ContentControl));
|
||||||
services.AddNavigateHandler<FrameHandler>();
|
services.AddHandler<FrameHandler>(nameof(Frame));
|
||||||
services.AddNavigateHandler<ContentDialogHandler>();
|
services.AddHandler<ContentDialogHandler>(nameof(ContentDialog));
|
||||||
})));
|
})));
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class AppService(IEnumerable<IInitializer> initializers,
|
public class AppService(IEnumerable<IInitialization> initializers,
|
||||||
IPublisher publisher) :
|
IPublisher publisher) :
|
||||||
IHostedService
|
IHostedService
|
||||||
{
|
{
|
||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
foreach (IInitializer initializer in initializers)
|
foreach (IInitialization initializer in initializers)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public record ChangedEventArgs<TSender>(TSender? Sender = default);
|
public record ChangedEventArgs<TSender>(TSender? Sender = default);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public partial class CommandValueViewModel<TValue>(IServiceProvider provider,
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ValueViewModel<TValue>(provider, factory, mediator, publisher, subscriber, disposer)
|
ValueViewModel<TValue>(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public partial class CommandViewModel(IServiceProvider provider,
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
Observable(provider, factory, mediator, publisher, subscriber, disposer)
|
Observable(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,14 +32,13 @@ public class ComponentBuilder :
|
|||||||
services.AddScoped<SubscriptionCollection>();
|
services.AddScoped<SubscriptionCollection>();
|
||||||
|
|
||||||
services.AddTransient<IHandlerProvider, HandlerProvider>();
|
services.AddTransient<IHandlerProvider, HandlerProvider>();
|
||||||
services.AddScoped<ISubscription, Subscription>();
|
services.AddScoped<ISubscriber, Subscriber>();
|
||||||
|
|
||||||
services.AddTransient<IPublisher, Publisher>();
|
services.AddTransient<IPublisher, Publisher>();
|
||||||
|
|
||||||
services.AddTransient<IMediator, Mediator>();
|
services.AddTransient<IMediator, Mediator>();
|
||||||
|
|
||||||
|
services.AddTransient<IContentFactory, ContentFactory>();
|
||||||
services.AddTransient<INavigationScope, NavigationScope>();
|
services.AddTransient<INavigationScope, NavigationScope>();
|
||||||
|
|
||||||
services.AddTransient<INavigationProvider, NavigationProvider>();
|
|
||||||
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
||||||
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public partial class ComponentConfigurationViewModel<TConfiguration, TValue, THe
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
THeader header,
|
THeader header,
|
||||||
TDescription description,
|
TDescription description,
|
||||||
@@ -30,7 +30,7 @@ public partial class ComponentConfigurationViewModel<TConfiguration, TValue, TAc
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TAction action,
|
TAction action,
|
||||||
TConfiguration configuration,
|
TConfiguration configuration,
|
||||||
@@ -72,7 +72,7 @@ public partial class ComponentConfigurationViewModel<TConfiguration, TValue, TDe
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TAction action,
|
TAction action,
|
||||||
TDescription description,
|
TDescription description,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Microsoft.Extensions.Hosting;
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class ComponentHost(IServiceProvider services,
|
public class ComponentHost(IServiceProvider services,
|
||||||
IEnumerable<IInitializer> initializers,
|
IEnumerable<IInitialization> initializers,
|
||||||
IEnumerable<IHostedService> hostedServices) :
|
IEnumerable<IHostedService> hostedServices) :
|
||||||
IComponentHost
|
IComponentHost
|
||||||
{
|
{
|
||||||
@@ -21,7 +21,7 @@ public class ComponentHost(IServiceProvider services,
|
|||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken = default)
|
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
foreach (IInitializer initializer in initializers)
|
foreach (IInitialization initializer in initializers)
|
||||||
{
|
{
|
||||||
await initializer.Initialize();
|
await initializer.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public class ComponentInitializer(IEnumerable<IComponent> components,
|
|||||||
IComponentHostCollection hosts,
|
IComponentHostCollection hosts,
|
||||||
IComponentScopeCollection scopes,
|
IComponentScopeCollection scopes,
|
||||||
IServiceProvider provider) :
|
IServiceProvider provider) :
|
||||||
IInitializer
|
IInitialization
|
||||||
{
|
{
|
||||||
public async Task Initialize()
|
public async Task Initialize()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ public class ConfigurationInitializer<TConfiguration>(IConfigurationReader<TConf
|
|||||||
IConfigurationFactory<TConfiguration> factory,
|
IConfigurationFactory<TConfiguration> factory,
|
||||||
IPublisher publisher) :
|
IPublisher publisher) :
|
||||||
IConfigurationInitializer<TConfiguration>,
|
IConfigurationInitializer<TConfiguration>,
|
||||||
IInitializer
|
IInitialization
|
||||||
where TConfiguration :
|
where TConfiguration :
|
||||||
class
|
class
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public class ContentFactory(IMediator mediator,
|
||||||
|
IServiceProvider provider,
|
||||||
|
IServiceFactory factory) : IContentFactory
|
||||||
|
{
|
||||||
|
public async Task<object?> CreateAsync(IContentTemplateDescriptor descriptor,
|
||||||
|
object[] parameters)
|
||||||
|
{
|
||||||
|
Type createEventType = typeof(CreateEventArgs<>).MakeGenericType(descriptor.ContentType);
|
||||||
|
|
||||||
|
object? content = null;
|
||||||
|
if (Activator.CreateInstance(createEventType, [null, parameters]) is object createEvent)
|
||||||
|
{
|
||||||
|
content = await mediator.Handle(descriptor.ContentType, createEvent, descriptor.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content is null)
|
||||||
|
{
|
||||||
|
if (parameters is { Length: > 0 })
|
||||||
|
{
|
||||||
|
content = factory.Create(descriptor.ContentType, args =>
|
||||||
|
{
|
||||||
|
if (args is IPostInitialization initialization)
|
||||||
|
{
|
||||||
|
initialization.PostInitialize();
|
||||||
|
}
|
||||||
|
}, parameters);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content = provider.GetRequiredKeyedService(descriptor.ContentType, args =>
|
||||||
|
{
|
||||||
|
if (args is IPostInitialization initialization)
|
||||||
|
{
|
||||||
|
initialization.PostInitialize();
|
||||||
|
}
|
||||||
|
}, descriptor.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public class ContentTemplateDescriptorProvider(IEnumerable<IContentTemplateDescriptor> contentTemplates) :
|
|
||||||
IContentTemplateDescriptorProvider
|
|
||||||
{
|
|
||||||
public IContentTemplateDescriptor? Get(object key)
|
|
||||||
{
|
|
||||||
if (contentTemplates.FirstOrDefault(x => x.Key.Equals(key) || x.Key.Equals($"{key}".Replace("ViewModel", "")))
|
|
||||||
is IContentTemplateDescriptor viewModelTemplate)
|
|
||||||
{
|
|
||||||
return viewModelTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,9 +29,9 @@ public class DefaultHostBuilder :
|
|||||||
services.AddScoped<SubscriptionCollection>();
|
services.AddScoped<SubscriptionCollection>();
|
||||||
|
|
||||||
services.AddTransient<IHandlerProvider, HandlerProvider>();
|
services.AddTransient<IHandlerProvider, HandlerProvider>();
|
||||||
services.AddTransient<ISubscription, Subscription>();
|
services.AddTransient<ISubscriber, Subscriber>();
|
||||||
|
|
||||||
services.AddTransient<ISubscription, Subscription>();
|
services.AddTransient<ISubscriber, Subscriber>();
|
||||||
|
|
||||||
services.AddTransient<IPublisher, Publisher>();
|
services.AddTransient<IPublisher, Publisher>();
|
||||||
services.AddTransient<IMediator, Mediator>();
|
services.AddTransient<IMediator, Mediator>();
|
||||||
@@ -45,9 +45,7 @@ public class DefaultHostBuilder :
|
|||||||
services.AddScoped<IProxyService<IComponentHostCollection>>(provider =>
|
services.AddScoped<IProxyService<IComponentHostCollection>>(provider =>
|
||||||
new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>()));
|
new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>()));
|
||||||
|
|
||||||
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
|
services.AddTransient<IContentFactory, ContentFactory>();
|
||||||
|
|
||||||
services.AddTransient<INavigationProvider, NavigationProvider>();
|
|
||||||
|
|
||||||
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
||||||
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public interface IConfigurationChanged<TConfiguration> :
|
public interface IConfigurationChanged<TConfiguration> :
|
||||||
IInitializer;
|
IInitialization;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
namespace Toolkit.Foundation
|
||||||
|
{
|
||||||
|
public interface IContentFactory
|
||||||
|
{
|
||||||
|
Task<object?> CreateAsync(IContentTemplateDescriptor descriptor, object[] resolvedArguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public interface IContentTemplateDescriptorProvider
|
|
||||||
{
|
|
||||||
IContentTemplateDescriptor? Get(object key);
|
|
||||||
}
|
|
||||||
@@ -156,7 +156,7 @@ public static class IHostBuilderExtension
|
|||||||
services.TryAddKeyedTransient<IConfigurationFactory<TConfiguration>>(section, (provider, key) =>
|
services.TryAddKeyedTransient<IConfigurationFactory<TConfiguration>>(section, (provider, key) =>
|
||||||
new ConfigurationFactory<TConfiguration>(() => defaultConfiguration ?? provider.GetRequiredKeyedService<TConfiguration>(key)));
|
new ConfigurationFactory<TConfiguration>(() => defaultConfiguration ?? provider.GetRequiredKeyedService<TConfiguration>(key)));
|
||||||
|
|
||||||
services.AddTransient<IInitializer, ConfigurationInitializer<TConfiguration>>(provider =>
|
services.AddTransient<IInitialization, ConfigurationInitializer<TConfiguration>>(provider =>
|
||||||
new ConfigurationInitializer<TConfiguration>(provider.GetRequiredKeyedService<IConfigurationReader<TConfiguration>>(section),
|
new ConfigurationInitializer<TConfiguration>(provider.GetRequiredKeyedService<IConfigurationReader<TConfiguration>>(section),
|
||||||
provider.GetRequiredKeyedService<IConfigurationWriter<TConfiguration>>(section),
|
provider.GetRequiredKeyedService<IConfigurationWriter<TConfiguration>>(section),
|
||||||
provider.GetRequiredKeyedService<IConfigurationFactory<TConfiguration>>(section),
|
provider.GetRequiredKeyedService<IConfigurationFactory<TConfiguration>>(section),
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public interface IInitializer
|
public interface IInitialization
|
||||||
{
|
{
|
||||||
Task Initialize();
|
Task Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IInitializer<T>
|
public interface IInitialization<T>
|
||||||
{
|
{
|
||||||
Task<T> Initialize();
|
Task<T> Initialize();
|
||||||
}
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public interface INavigationProvider
|
|
||||||
{
|
|
||||||
INavigation? Get(Type type);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public interface IPostInitialization
|
||||||
|
{
|
||||||
|
void PostInitialize();
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public static class IServiceCollectionExtensions
|
public static class IServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddCache<TKey, TValue>(this IServiceCollection services)
|
public static IServiceCollection AddCache<TKey, TValue>(this IServiceCollection services)
|
||||||
@@ -132,31 +130,9 @@ public static class IServiceCollectionExtensions
|
|||||||
|
|
||||||
public static IServiceCollection AddInitializer<TInitializer>(this IServiceCollection services)
|
public static IServiceCollection AddInitializer<TInitializer>(this IServiceCollection services)
|
||||||
where TInitializer : class,
|
where TInitializer : class,
|
||||||
IInitializer
|
IInitialization
|
||||||
{
|
{
|
||||||
services.AddTransient<IInitializer, TInitializer>();
|
services.AddTransient<IInitialization, TInitializer>();
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddNavigateHandler<THandler>(this IServiceCollection services)
|
|
||||||
where THandler : INavigateHandler,
|
|
||||||
IHandler
|
|
||||||
{
|
|
||||||
IEnumerable<Type> contracts = typeof(THandler).GetInterfaces()
|
|
||||||
.Where(x => x.Name == typeof(INavigateHandler<>).Name || x.Name == typeof(INavigateBackHandler<>).Name);
|
|
||||||
|
|
||||||
foreach (Type contract in contracts)
|
|
||||||
{
|
|
||||||
if (contract.GetGenericArguments() is { Length: 1 } arguments)
|
|
||||||
{
|
|
||||||
services.AddTransient<INavigation>(provider => new Navigation
|
|
||||||
{
|
|
||||||
Type = arguments[0]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
services.AddHandler<THandler>();
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +181,7 @@ public static class IServiceCollectionExtensions
|
|||||||
|
|
||||||
services.Add(new ServiceDescriptor(viewType, key, viewType, serviceLifetime));
|
services.Add(new ServiceDescriptor(viewType, key, viewType, serviceLifetime));
|
||||||
|
|
||||||
services.AddTransient<IContentTemplateDescriptor>(provider =>
|
services.AddKeyedTransient<IContentTemplateDescriptor>(key, (provider, _) =>
|
||||||
new ContentTemplateDescriptor(key, viewModelType, viewType, parameters));
|
new ContentTemplateDescriptor(key, viewModelType, viewType, parameters));
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|||||||
@@ -7,5 +7,8 @@ public interface IServiceFactory
|
|||||||
TService Create<TService>(Action<TService> serviceDelegate,
|
TService Create<TService>(Action<TService> serviceDelegate,
|
||||||
params object?[]? parameters);
|
params object?[]? parameters);
|
||||||
|
|
||||||
|
object Create(Type type, Action<object> serviceDelegate,
|
||||||
|
params object?[]? parameters);
|
||||||
|
|
||||||
TService Create<TService>(params object?[]? parameters);
|
TService Create<TService>(params object?[]? parameters);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public static class IServiceProviderExtensions
|
||||||
|
{
|
||||||
|
public static object GetRequiredKeyedService(this IServiceProvider provider,
|
||||||
|
Type serviceType,
|
||||||
|
Action<object> serviceDelegate,
|
||||||
|
object? serviceKey)
|
||||||
|
{
|
||||||
|
object service = provider.GetRequiredKeyedService(serviceType, serviceKey);
|
||||||
|
serviceDelegate.Invoke(service);
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public interface ISubscriber
|
||||||
|
{
|
||||||
|
void Subscribe(object subscriber);
|
||||||
|
|
||||||
|
void Unsubscribe(object subscriber);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public interface ISubscriberRequired
|
||||||
|
{
|
||||||
|
ISubscriber Subscription { get; }
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public interface ISubscription
|
|
||||||
{
|
|
||||||
void Add(object subscriber);
|
|
||||||
|
|
||||||
void Remove(object subscriber);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public interface ISubscriptionRequired
|
|
||||||
{
|
|
||||||
ISubscription Subscription { get; }
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public class NavigationProvider(IEnumerable<INavigation> navigations) :
|
|
||||||
INavigationProvider
|
|
||||||
{
|
|
||||||
public INavigation? Get(Type type)
|
|
||||||
{
|
|
||||||
if (navigations.FirstOrDefault(x => type == x.Type ||
|
|
||||||
type.BaseType == x.Type) is INavigation navigation)
|
|
||||||
{
|
|
||||||
return navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class NavigationRegionProvider(INavigationRegionCollection contexts) :
|
public class NavigationRegionProvider(INavigationRegionCollection collection) :
|
||||||
INavigationRegionProvider
|
INavigationRegionProvider
|
||||||
{
|
{
|
||||||
public object? Get(object key) =>
|
public object? Get(object key) =>
|
||||||
contexts.TryGetValue(key, out object? target) ? target : default;
|
collection.TryGetValue(key, out object? target) ? target : default;
|
||||||
|
|
||||||
public bool TryGet(object name,
|
public bool TryGet(object name,
|
||||||
out object? value)
|
out object? value)
|
||||||
{
|
{
|
||||||
if (contexts.TryGetValue(name,
|
if (collection.TryGetValue(name,
|
||||||
out object? target))
|
out object? target))
|
||||||
{
|
{
|
||||||
value = target;
|
value = target;
|
||||||
|
|||||||
@@ -2,13 +2,10 @@
|
|||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class NavigationScope(IPublisher publisher,
|
public class NavigationScope(IServiceProvider provider,
|
||||||
IMediator mediator,
|
|
||||||
IServiceProvider provider,
|
|
||||||
IServiceFactory factory,
|
|
||||||
INavigationProvider navigationProvider,
|
|
||||||
INavigationRegionProvider navigationRegionProvider,
|
INavigationRegionProvider navigationRegionProvider,
|
||||||
IContentTemplateDescriptorProvider contentTemplateDescriptorProvider) :
|
IContentFactory contentFactory,
|
||||||
|
IPublisher publisher) :
|
||||||
INavigationScope
|
INavigationScope
|
||||||
{
|
{
|
||||||
public async void Navigate(string route,
|
public async void Navigate(string route,
|
||||||
@@ -30,7 +27,7 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
{
|
{
|
||||||
currentSegmentIndex++;
|
currentSegmentIndex++;
|
||||||
|
|
||||||
if (contentTemplateDescriptorProvider.Get(segment)
|
if (provider.GetKeyedService<IContentTemplateDescriptor>(segment)
|
||||||
is IContentTemplateDescriptor descriptor)
|
is IContentTemplateDescriptor descriptor)
|
||||||
{
|
{
|
||||||
Dictionary<string, object>? arguments = parameters?.ToDictionary(x => x.Key, x => x.Value, StringComparer.InvariantCultureIgnoreCase) ?? [];
|
Dictionary<string, object>? arguments = parameters?.ToDictionary(x => x.Key, x => x.Value, StringComparer.InvariantCultureIgnoreCase) ?? [];
|
||||||
@@ -42,14 +39,15 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
.TryGetValue(x.Name, out object? argument) ? argument : default)
|
.TryGetValue(x.Name, out object? argument) ? argument : default)
|
||||||
.Where(argument => argument is not null)] : [];
|
.Where(argument => argument is not null)] : [];
|
||||||
|
|
||||||
if (provider.GetRequiredKeyedService(descriptor.TemplateType, segment) is object view)
|
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key)
|
||||||
|
is object template)
|
||||||
{
|
{
|
||||||
if (region is not null)
|
if (region is not null)
|
||||||
{
|
{
|
||||||
switch (region)
|
switch (region)
|
||||||
{
|
{
|
||||||
case "self":
|
case "self":
|
||||||
region = view;
|
region = template;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -64,38 +62,18 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
|
|
||||||
if (region is not null)
|
if (region is not null)
|
||||||
{
|
{
|
||||||
Type createEventType = typeof(CreateEventArgs<>).MakeGenericType(descriptor.ContentType);
|
object? content = await contentFactory.CreateAsync(descriptor, resolvedArguments);
|
||||||
|
|
||||||
object? content = null;
|
|
||||||
if (Activator.CreateInstance(createEventType, [null, resolvedArguments]) is object createEvent)
|
|
||||||
{
|
|
||||||
content = await mediator.Handle(descriptor.ContentType, createEvent, descriptor.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content is null)
|
|
||||||
{
|
|
||||||
if (resolvedArguments is { Length: > 0 })
|
|
||||||
{
|
|
||||||
content = factory.Create(descriptor.ContentType, resolvedArguments);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
content = provider.GetRequiredKeyedService(descriptor.ContentType, segment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content is not null)
|
if (content is not null)
|
||||||
{
|
{
|
||||||
if (navigationProvider.Get(region is Type type ? type : region.GetType()) is INavigation navigation)
|
Type navigationType = region is Type type ? type : region.GetType();
|
||||||
|
Type navigateEventType = typeof(NavigateEventArgs<>).MakeGenericType(navigationType);
|
||||||
|
if (Activator.CreateInstance(navigateEventType, [region, template, content, sender, parameters])
|
||||||
|
is object navigateEvent)
|
||||||
{
|
{
|
||||||
Type navigateEventType = typeof(NavigateEventArgs<>).MakeGenericType(navigation.Type);
|
publisher.Publish(navigateEvent, navigationType.Name);
|
||||||
if (Activator.CreateInstance(navigateEventType, [region, view, content, sender, parameters]) is object navigateEvent)
|
if (currentSegmentIndex == segmentCount)
|
||||||
{
|
{
|
||||||
publisher.Publish(navigateEvent);
|
navigated?.Invoke(this, EventArgs.Empty);
|
||||||
if (currentSegmentIndex == segmentCount)
|
|
||||||
{
|
|
||||||
navigated?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,14 +92,11 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
|
|
||||||
if (region is not null)
|
if (region is not null)
|
||||||
{
|
{
|
||||||
if (navigationProvider.Get(region is Type type ? type : region.GetType())
|
Type navigationType = region is Type type ? type : region.GetType();
|
||||||
is INavigation navigation)
|
Type navigateType = typeof(NavigateBackEventArgs<>).MakeGenericType(navigationType);
|
||||||
|
if (Activator.CreateInstance(navigateType, [region]) is object navigate)
|
||||||
{
|
{
|
||||||
Type navigateType = typeof(NavigateBackEventArgs<>).MakeGenericType(navigation.Type);
|
publisher.Publish(navigate);
|
||||||
if (Activator.CreateInstance(navigateType, [region]) is object navigate)
|
|
||||||
{
|
|
||||||
publisher.Publish(navigate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
|
||||||
public class NavigationTargetAttribute(string name) :
|
|
||||||
Attribute
|
|
||||||
{
|
|
||||||
public string Name => name;
|
|
||||||
}
|
|
||||||
@@ -2,11 +2,18 @@
|
|||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public partial class Observable :
|
public partial class Observable(IServiceProvider
|
||||||
|
provider,
|
||||||
|
IServiceFactory factory,
|
||||||
|
IMediator mediator,
|
||||||
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer) :
|
||||||
ObservableObject,
|
ObservableObject,
|
||||||
IObservableViewModel,
|
IObservableViewModel,
|
||||||
IActivityIndicator,
|
IActivityIndicator,
|
||||||
IInitializer,
|
IPostInitialization,
|
||||||
|
IInitialization,
|
||||||
IActivated,
|
IActivated,
|
||||||
IDeactivating,
|
IDeactivating,
|
||||||
IDeactivated,
|
IDeactivated,
|
||||||
@@ -20,40 +27,25 @@ public partial class Observable :
|
|||||||
{
|
{
|
||||||
private readonly Dictionary<string, object> trackedProperties = [];
|
private readonly Dictionary<string, object> trackedProperties = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool initialized;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool active;
|
private bool active;
|
||||||
|
|
||||||
public Observable(IServiceProvider
|
[ObservableProperty]
|
||||||
provider,
|
private bool initialized;
|
||||||
IServiceFactory factory,
|
private bool postInitialized;
|
||||||
IMediator mediator,
|
|
||||||
IPublisher publisher,
|
|
||||||
ISubscription subscriber,
|
|
||||||
IDisposer disposer)
|
|
||||||
{
|
|
||||||
Provider = provider;
|
|
||||||
Factory = factory;
|
|
||||||
Mediator = mediator;
|
|
||||||
Publisher = publisher;
|
|
||||||
Disposer = disposer;
|
|
||||||
|
|
||||||
subscriber.Add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler? DeactivateHandler;
|
public event EventHandler? DeactivateHandler;
|
||||||
|
|
||||||
public IDisposer Disposer { get; }
|
public IDisposer Disposer { get; } = disposer;
|
||||||
|
|
||||||
public IServiceFactory Factory { get; }
|
public IServiceFactory Factory { get; } = factory;
|
||||||
|
|
||||||
public IMediator Mediator { get; }
|
public IMediator Mediator { get; } = mediator;
|
||||||
|
|
||||||
public IServiceProvider Provider { get; }
|
public IServiceProvider Provider { get; } = provider;
|
||||||
|
|
||||||
public IPublisher Publisher { get; }
|
public IPublisher Publisher { get; } = publisher;
|
||||||
|
public ISubscriber Subscriber { get; } = subscriber;
|
||||||
|
|
||||||
public void Commit()
|
public void Commit()
|
||||||
{
|
{
|
||||||
@@ -95,6 +87,17 @@ public partial class Observable :
|
|||||||
public virtual Task OnDeactivating() =>
|
public virtual Task OnDeactivating() =>
|
||||||
Task.CompletedTask;
|
Task.CompletedTask;
|
||||||
|
|
||||||
|
public virtual void PostInitialize()
|
||||||
|
{
|
||||||
|
if (postInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
postInitialized = true;
|
||||||
|
Subscriber.Subscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
foreach (object trackedProperty in trackedProperties.Values)
|
foreach (object trackedProperty in trackedProperties.Values)
|
||||||
@@ -124,7 +127,7 @@ public partial class Observable<TValue> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
@@ -154,7 +157,7 @@ public partial class Observable<TKey, TValue> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TKey key,
|
TKey key,
|
||||||
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ namespace Toolkit.Foundation;
|
|||||||
public partial class ObservableCollection<TItem> :
|
public partial class ObservableCollection<TItem> :
|
||||||
ObservableObject,
|
ObservableObject,
|
||||||
IObservableCollectionViewModel<TItem>,
|
IObservableCollectionViewModel<TItem>,
|
||||||
IInitializer,
|
IPostInitialization,
|
||||||
|
IInitialization,
|
||||||
IActivated,
|
IActivated,
|
||||||
IDeactivating,
|
IDeactivating,
|
||||||
IDeactivated,
|
IDeactivated,
|
||||||
@@ -32,7 +33,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 : notnull,
|
where TItem : notnull,
|
||||||
IDisposable
|
IDisposable
|
||||||
{
|
{
|
||||||
private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = [];
|
private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = [];
|
||||||
@@ -52,6 +53,8 @@ public partial class ObservableCollection<TItem> :
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool initialized;
|
private bool initialized;
|
||||||
|
|
||||||
|
private bool postInitialized;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private TItem? selectedItem;
|
private TItem? selectedItem;
|
||||||
|
|
||||||
@@ -59,17 +62,16 @@ public partial class ObservableCollection<TItem> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer)
|
IDisposer disposer)
|
||||||
{
|
{
|
||||||
Provider = provider;
|
Provider = provider;
|
||||||
Factory = factory;
|
Factory = factory;
|
||||||
Mediator = mediator;
|
Mediator = mediator;
|
||||||
Publisher = publisher;
|
Publisher = publisher;
|
||||||
|
Subscriber = subscriber;
|
||||||
Disposer = disposer;
|
Disposer = disposer;
|
||||||
|
|
||||||
subscriber.Add(this);
|
|
||||||
|
|
||||||
dispatcher = Provider.GetRequiredService<IDispatcher>();
|
dispatcher = Provider.GetRequiredService<IDispatcher>();
|
||||||
collection.CollectionChanged += OnCollectionChanged;
|
collection.CollectionChanged += OnCollectionChanged;
|
||||||
}
|
}
|
||||||
@@ -78,7 +80,7 @@ public partial class ObservableCollection<TItem> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<TItem> items)
|
IEnumerable<TItem> items)
|
||||||
{
|
{
|
||||||
@@ -86,10 +88,9 @@ public partial class ObservableCollection<TItem> :
|
|||||||
Factory = factory;
|
Factory = factory;
|
||||||
Mediator = mediator;
|
Mediator = mediator;
|
||||||
Publisher = publisher;
|
Publisher = publisher;
|
||||||
|
Subscriber = subscriber;
|
||||||
Disposer = disposer;
|
Disposer = disposer;
|
||||||
|
|
||||||
subscriber.Add(this);
|
|
||||||
|
|
||||||
dispatcher = Provider.GetRequiredService<IDispatcher>();
|
dispatcher = Provider.GetRequiredService<IDispatcher>();
|
||||||
collection.CollectionChanged += OnCollectionChanged;
|
collection.CollectionChanged += OnCollectionChanged;
|
||||||
|
|
||||||
@@ -117,6 +118,7 @@ public partial class ObservableCollection<TItem> :
|
|||||||
public IServiceProvider Provider { get; private set; }
|
public IServiceProvider Provider { get; private set; }
|
||||||
|
|
||||||
public IPublisher Publisher { get; private set; }
|
public IPublisher Publisher { get; private set; }
|
||||||
|
public ISubscriber Subscriber { get; }
|
||||||
|
|
||||||
object ICollection.SyncRoot => this;
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
@@ -149,18 +151,19 @@ public partial class ObservableCollection<TItem> :
|
|||||||
where T :
|
where T :
|
||||||
TItem
|
TItem
|
||||||
{
|
{
|
||||||
T? item = Factory.Create<T>(parameters);
|
T? item = Factory.Create<T>(args =>
|
||||||
|
{
|
||||||
|
if (args is IPostInitialization initialization)
|
||||||
|
{
|
||||||
|
initialization.PostInitialize();
|
||||||
|
}
|
||||||
|
}, parameters);
|
||||||
|
|
||||||
Add(item);
|
Add(item);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear(Action<ObservableCollection<TItem>> factory)
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
factory.Invoke(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(TItem item)
|
public void Add(TItem item)
|
||||||
{
|
{
|
||||||
int index = collection.Count;
|
int index = collection.Count;
|
||||||
@@ -200,6 +203,11 @@ public partial class ObservableCollection<TItem> :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Clear(Action<ObservableCollection<TItem>> factory)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
factory.Invoke(this);
|
||||||
|
}
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
clearing = true;
|
clearing = true;
|
||||||
@@ -246,17 +254,6 @@ public partial class ObservableCollection<TItem> :
|
|||||||
Disposer.Dispose(this);
|
Disposer.Dispose(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Fetch(bool reset = false)
|
|
||||||
{
|
|
||||||
if (reset)
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SynchronizeExpression expression = BuildAggregateExpression();
|
|
||||||
Publisher.PublishUI(expression.Value, expression.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Fetch(Func<SynchronizeExpression> aggregateDelegate,
|
public void Fetch(Func<SynchronizeExpression> aggregateDelegate,
|
||||||
bool reset = false)
|
bool reset = false)
|
||||||
{
|
{
|
||||||
@@ -268,6 +265,7 @@ public partial class ObservableCollection<TItem> :
|
|||||||
SynchronizeExpression expression = aggregateDelegate.Invoke();
|
SynchronizeExpression expression = aggregateDelegate.Invoke();
|
||||||
Publisher.PublishUI(expression.Value, expression.Key);
|
Publisher.PublishUI(expression.Value, expression.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<TItem> GetEnumerator() =>
|
public IEnumerator<TItem> GetEnumerator() =>
|
||||||
collection.GetEnumerator();
|
collection.GetEnumerator();
|
||||||
|
|
||||||
@@ -413,7 +411,7 @@ public partial class ObservableCollection<TItem> :
|
|||||||
}
|
}
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
Fetch();
|
Synchronize();
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -423,14 +421,21 @@ public partial class ObservableCollection<TItem> :
|
|||||||
where T :
|
where T :
|
||||||
TItem
|
TItem
|
||||||
{
|
{
|
||||||
T? item = Factory.Create<T>(parameters);
|
T? item = Factory.Create<T>(args =>
|
||||||
|
{
|
||||||
|
if (args is IPostInitialization initialization)
|
||||||
|
{
|
||||||
|
initialization.PostInitialize();
|
||||||
|
}
|
||||||
|
}, parameters);
|
||||||
|
|
||||||
InsertItem(index, item);
|
InsertItem(index, item);
|
||||||
UpdateSelection(item);
|
UpdateSelection(item);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Insert(int index,
|
public void Insert(int index,
|
||||||
TItem item)
|
TItem item)
|
||||||
{
|
{
|
||||||
InsertItem(index, item);
|
InsertItem(index, item);
|
||||||
@@ -516,6 +521,17 @@ public partial class ObservableCollection<TItem> :
|
|||||||
public virtual Task OnDeactivating() =>
|
public virtual Task OnDeactivating() =>
|
||||||
Task.CompletedTask;
|
Task.CompletedTask;
|
||||||
|
|
||||||
|
public virtual void PostInitialize()
|
||||||
|
{
|
||||||
|
if (postInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
postInitialized = true;
|
||||||
|
Subscriber.Subscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Remove(TItem item)
|
public bool Remove(TItem item)
|
||||||
{
|
{
|
||||||
int index = collection.IndexOf(item);
|
int index = collection.IndexOf(item);
|
||||||
@@ -574,6 +590,16 @@ public partial class ObservableCollection<TItem> :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Synchronize(bool reset = false)
|
||||||
|
{
|
||||||
|
if (reset)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SynchronizeExpression expression = BuildAggregateExpression();
|
||||||
|
Publisher.PublishUI(expression.Value, expression.Key);
|
||||||
|
}
|
||||||
public void Track<T>(string propertyName, Func<T> getter, Action<T> setter)
|
public void Track<T>(string propertyName, Func<T> getter, Action<T> setter)
|
||||||
{
|
{
|
||||||
if (!trackedProperties.ContainsKey(propertyName))
|
if (!trackedProperties.ContainsKey(propertyName))
|
||||||
@@ -657,7 +683,7 @@ public partial class ObservableCollection<TValue, TViewModel>(IServiceProvider p
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TValue value) : ObservableCollection<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer)
|
TValue value) : ObservableCollection<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
where TViewModel : notnull, IDisposable
|
where TViewModel : notnull, IDisposable
|
||||||
@@ -690,7 +716,7 @@ public partial class ObservableCollection<TViewModel, TKey, TValue> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
TKey key,
|
TKey key,
|
||||||
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
TValue value) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
@@ -703,7 +729,7 @@ public partial class ObservableCollection<TViewModel, TKey, TValue> :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<TViewModel> items,
|
IEnumerable<TViewModel> items,
|
||||||
TKey key,
|
TKey key,
|
||||||
@@ -728,7 +754,7 @@ public class ObservableCollection :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -737,7 +763,7 @@ public class ObservableCollection :
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<IDisposable> items) : base(provider, factory, mediator, publisher, subscriber, disposer, items)
|
IEnumerable<IDisposable> items) : base(provider, factory, mediator, publisher, subscriber, disposer, items)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,4 +17,13 @@ public class ServiceFactory(Func<Type, object?[]?, object> factory) :
|
|||||||
|
|
||||||
public object Create(Type type, params object?[]? parameters) =>
|
public object Create(Type type, params object?[]? parameters) =>
|
||||||
factory(type, parameters);
|
factory(type, parameters);
|
||||||
|
|
||||||
|
public object Create(Type type, Action<object> serviceDelegate,
|
||||||
|
params object?[]? parameters)
|
||||||
|
{
|
||||||
|
object service = factory(type, parameters);
|
||||||
|
serviceDelegate.Invoke(service);
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class Subscription(SubscriptionCollection subscriptions,
|
public class Subscriber(SubscriptionCollection subscriptions,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ISubscription
|
ISubscriber
|
||||||
{
|
{
|
||||||
public void Add(object subscriber)
|
public void Subscribe(object subscriber)
|
||||||
{
|
{
|
||||||
Type handlerType = subscriber.GetType();
|
Type handlerType = subscriber.GetType();
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public class Subscription(SubscriptionCollection subscriptions,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(object subscriber)
|
public void Unsubscribe(object subscriber)
|
||||||
{
|
{
|
||||||
Type handlerType = subscriber.GetType();
|
Type handlerType = subscriber.GetType();
|
||||||
IDictionary<Type, List<object>> subscribers = GetSubscriptionKeys(subscriber);
|
IDictionary<Type, List<object>> subscribers = GetSubscriptionKeys(subscriber);
|
||||||
@@ -6,7 +6,7 @@ public partial class ValueViewModel<TValue>(IServiceProvider provider,
|
|||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscription subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
Observable(provider, factory, mediator, publisher, subscriber, disposer)
|
Observable(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user