From 858a23c28dca1579dffa789200cd6bc43cdc0cc4 Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Tue, 30 Jan 2024 22:30:08 +0000 Subject: [PATCH] A widget should have only one IWidgetViewModel by default... wondering whether if we should go for the first served, or throw if multiple detected, or ignore the widget --- .../ContextualWidget.cs | 17 ++-- .../MediaControllerWidget.cs | 40 ++++---- .../PrimaryWidget.cs | 49 +++++----- .../IServiceCollectionExtensions.cs | 5 +- .../WidgetContainerView.xaml | 35 ------- .../WidgetContainerView.xaml.cs | 9 -- Hyperbar.Widget/IWidgetBuilder.cs | 18 ++-- Hyperbar.Widget/WidgetBarViewModel.cs | 6 +- Hyperbar.Widget/WidgetBuilder.cs | 96 ++++++++++++------- Hyperbar.Widget/WidgetContainerFactory.cs | 10 -- Hyperbar.Widget/WidgetContainerViewModel.cs | 19 ---- Hyperbar.Widget/WidgetHostHandler.cs | 9 +- Hyperbar.Widget/WidgetViewModelEnumerator.cs | 2 +- Hyperbar.Windows/Lifecycles/AppInitializer.cs | 4 +- 14 files changed, 139 insertions(+), 180 deletions(-) delete mode 100644 Hyperbar.Widget.Windows/WidgetContainerView.xaml delete mode 100644 Hyperbar.Widget.Windows/WidgetContainerView.xaml.cs delete mode 100644 Hyperbar.Widget/WidgetContainerFactory.cs delete mode 100644 Hyperbar.Widget/WidgetContainerViewModel.cs diff --git a/Hyperbar.Widget.Contextual.Windows/ContextualWidget.cs b/Hyperbar.Widget.Contextual.Windows/ContextualWidget.cs index 5de12e2..82b8865 100644 --- a/Hyperbar.Widget.Contextual.Windows/ContextualWidget.cs +++ b/Hyperbar.Widget.Contextual.Windows/ContextualWidget.cs @@ -4,12 +4,15 @@ public class ContextualWidget : IWidget { public IWidgetBuilder Create() => - WidgetBuilder.Configure(args => - { - args.Name = "Contextual commands"; + WidgetBuilder.Create() + .Configuration(args => + { + args.Name = "Contextual commands"; - }).ConfigureServices(args => - { - args.AddWidgetTemplate(); - }); + }) + .UseViewModel() + .ConfigureServices(args => + { + args.AddWidgetTemplate(); + }); } \ No newline at end of file diff --git a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidget.cs b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidget.cs index 75e7c4e..18f99f5 100644 --- a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidget.cs +++ b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidget.cs @@ -7,23 +7,25 @@ public class MediaControllerWidget : IWidget { public IWidgetBuilder Create() => - WidgetBuilder.Configure(args => - { - args.Name = "Media controller"; - }).ConfigureServices(args => - { - args.AddWidgetTemplate() - .AddSingleton() - .AddTransient, ServiceScopeFactory>() - .AddTransient, ServiceScopeProvider>() - .AddCache() - .AddTransient, MediaControllerFactory>() - .AddHandler() - .AddTransient, MediaControllerViewModelFactory>() - .AddCache() - .AddHandler() - .AddContentTemplate() - .AddContentTemplate() - .AddContentTemplate(); - }); + WidgetBuilder.Create() + .Configuration(args => + { + args.Name = "Media controller"; + }) + .UseViewModelTemplate() + .ConfigureServices(args => + { + args.AddSingleton() + .AddTransient, ServiceScopeFactory>() + .AddTransient, ServiceScopeProvider>() + .AddCache() + .AddTransient, MediaControllerFactory>() + .AddHandler() + .AddTransient, MediaControllerViewModelFactory>() + .AddCache() + .AddHandler() + .AddContentTemplate() + .AddContentTemplate() + .AddContentTemplate(); + }); } \ No newline at end of file diff --git a/Hyperbar.Widget.Primary.Windows/PrimaryWidget.cs b/Hyperbar.Widget.Primary.Windows/PrimaryWidget.cs index e087ba9..712335b 100644 --- a/Hyperbar.Widget.Primary.Windows/PrimaryWidget.cs +++ b/Hyperbar.Widget.Primary.Windows/PrimaryWidget.cs @@ -7,28 +7,29 @@ public class PrimaryWidget : IWidget { public IWidgetBuilder Create() => - WidgetBuilder.Configure(args => - { - args.Name = "Primary commands"; - args.Commands = - [ - new KeyAcceleratorCommandConfiguration - { - Id = Guid.NewGuid(), - Order = 0, - Text = "Test", - Icon = "dd", - Key = 1 - } - ]; - }).ConfigureServices(services => - { - services.AddCache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration>() - .AddCache() - .AddTransient, WidgetComponentProvider>() - .AddTransient, WidgetComponentFactory>() - .AddWidgetTemplate() - .AddHandler() - .AddHandler(); - }); + WidgetBuilder.Create() + .Configuration(args => + { + args.Name = "Primary commands"; + args.Commands = + [ + new KeyAcceleratorCommandConfiguration + { + Id = Guid.NewGuid(), + Order = 0, + Text = "Test", + Icon = "dd", + Key = 1 + } + ]; + }).ConfigureServices(services => + { + services.AddCache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration>() + .AddCache() + .AddTransient, WidgetComponentProvider>() + .AddTransient, WidgetComponentFactory>() + .AddWidgetTemplate() + .AddHandler() + .AddHandler(); + }); } \ No newline at end of file diff --git a/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs b/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs index 51e087a..f072acc 100644 --- a/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs +++ b/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs @@ -10,7 +10,7 @@ public static class IServiceCollectionExtensions { public static IServiceCollection AddWidgetWindows(this IServiceCollection services) { - services.AddContentTemplate(); + services.AddContentTemplate(); // We need to feed information to the Widgets about our Windows host, // so the Windows host can make discussions how to display and interact with the widgets. @@ -20,8 +20,6 @@ public static class IServiceCollectionExtensions { services.AddSingleton(provider.GetRequiredService>()); services.AddSingleton(provider.GetRequiredService()); - services.AddTransient, - WidgetContainerFactory>(); services.AddTransient(); @@ -35,7 +33,6 @@ public static class IServiceCollectionExtensions services.AddTransient(); services.AddTransient(); - services.AddContentTemplate(); services.AddContentTemplate(); services.AddContentTemplate(); })); diff --git a/Hyperbar.Widget.Windows/WidgetContainerView.xaml b/Hyperbar.Widget.Windows/WidgetContainerView.xaml deleted file mode 100644 index a9202de..0000000 --- a/Hyperbar.Widget.Windows/WidgetContainerView.xaml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/Hyperbar.Widget.Windows/WidgetContainerView.xaml.cs b/Hyperbar.Widget.Windows/WidgetContainerView.xaml.cs deleted file mode 100644 index 64d447a..0000000 --- a/Hyperbar.Widget.Windows/WidgetContainerView.xaml.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Microsoft.UI.Xaml.Controls; - -namespace Hyperbar.Widget.Windows; - -public sealed partial class WidgetContainerView : - UserControl -{ - public WidgetContainerView() => InitializeComponent(); -} diff --git a/Hyperbar.Widget/IWidgetBuilder.cs b/Hyperbar.Widget/IWidgetBuilder.cs index 1742ec2..0ce70c8 100644 --- a/Hyperbar.Widget/IWidgetBuilder.cs +++ b/Hyperbar.Widget/IWidgetBuilder.cs @@ -6,14 +6,18 @@ public interface IWidgetBuilder { IWidgetHost Build(); + IWidgetBuilder Configuration(Action configurationDelegate) + where TConfiguration : + WidgetConfiguration, + new(); + IWidgetBuilder ConfigureServices(Action configureDelegate); -} -public interface IWidgetBuilder : - IWidgetBuilder - where TConfiguration : - WidgetConfiguration, - new() -{ + IWidgetBuilder UseViewModel() + where TViewModel : + IWidgetViewModel; + IWidgetBuilder UseViewModelTemplate() + where TViewModel : + IWidgetViewModel; } \ No newline at end of file diff --git a/Hyperbar.Widget/WidgetBarViewModel.cs b/Hyperbar.Widget/WidgetBarViewModel.cs index e5197b7..60bb272 100644 --- a/Hyperbar.Widget/WidgetBarViewModel.cs +++ b/Hyperbar.Widget/WidgetBarViewModel.cs @@ -1,11 +1,11 @@ namespace Hyperbar.Widget; -[NotificationHandler(nameof(WidgetBarViewModel))] -public partial class WidgetBarViewModel(ITemplateFactory templateFactory, +[NotificationHandler(nameof(WidgetViewModel))] +public partial class WidgetViewModel(ITemplateFactory templateFactory, IServiceFactory serviceFactory, IMediator mediator, IDisposer disposer) : - ObservableCollectionViewModel(serviceFactory, mediator, disposer), + ObservableCollectionViewModel(serviceFactory, mediator, disposer), ITemplatedViewModel { public ITemplateFactory TemplateFactory => templateFactory; diff --git a/Hyperbar.Widget/WidgetBuilder.cs b/Hyperbar.Widget/WidgetBuilder.cs index 410aa51..e9031c9 100644 --- a/Hyperbar.Widget/WidgetBuilder.cs +++ b/Hyperbar.Widget/WidgetBuilder.cs @@ -5,47 +5,63 @@ using System.Reflection; namespace Hyperbar.Widget; -public class WidgetBuilder(TConfiguration configuration) : - IWidgetBuilder - where TConfiguration : - WidgetConfiguration, - new() +public class WidgetBuilder : + IWidgetBuilder { - private readonly IHostBuilder hostBuilder = new HostBuilder() - .UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + private readonly IHostBuilder hostBuilder; + + private WidgetBuilder() + { + hostBuilder = new HostBuilder() + .UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetEntryAssembly()?.GetName().Name!), true) - .ConfigureAppConfiguration(config => + .ConfigureAppConfiguration(config => + { + config.AddJsonFile("Settings.json", true, true); + }) + .ConfigureServices((context, services) => + { + services.AddSingleton(); + services.AddScoped(provider => + new ServiceFactory((type, parameters) => + ActivatorUtilities.CreateInstance(provider, type, parameters!))); + services.AddScoped(); + services.AddScoped(); + services.AddSingleton, Value>(); + }); + } + + public static IWidgetBuilder Create() => new WidgetBuilder(); + + public IWidgetBuilder Configuration(Action configurationDelegate) + where TConfiguration : + WidgetConfiguration, + new() + { + TConfiguration configuration = new TConfiguration(); + configurationDelegate(configuration); + + hostBuilder.ConfigureServices(services => { - config.AddJsonFile("Settings.json", true, true); - }) - .ConfigureServices((context, services) => - { - services.AddSingleton(); - - services.AddScoped(provider => - new ServiceFactory((type, parameters) => - ActivatorUtilities.CreateInstance(provider, type, parameters!))); - services.AddScoped(); - services.AddScoped(); - - services.AddSingleton, - Value>(); - services.AddHandler(); - - services.AddConfiguration(section: configuration.GetType().Name, - configuration: configuration); + services.AddConfiguration(section: configuration.GetType().Name, configuration: configuration); services.AddConfiguration(configuration); }); - public static IWidgetBuilder Configure(Action configurationDelegate) - { - TConfiguration configuration = new(); - configurationDelegate(configuration); - - return new WidgetBuilder(configuration); + return this; } + public IWidgetBuilder UseViewModelTemplate() + where TWidgetContent : + IWidgetViewModel + { + hostBuilder.ConfigureServices(services => + { + services.AddWidgetTemplate(); + }); + + return this; + } public IWidgetHost Build() { IHost host = hostBuilder.Build(); @@ -54,7 +70,19 @@ public class WidgetBuilder(TConfiguration configuration) : public IWidgetBuilder ConfigureServices(Action configureDelegate) { - hostBuilder.ConfigureServices(configureDelegate.Invoke); + hostBuilder.ConfigureServices(configureDelegate); return this; } -} \ No newline at end of file + + public IWidgetBuilder UseViewModel() + where TViewModel : + IWidgetViewModel + { + hostBuilder.ConfigureServices(services => + { + services.AddWidgetTemplate(); + }); + + return this; + } +} diff --git a/Hyperbar.Widget/WidgetContainerFactory.cs b/Hyperbar.Widget/WidgetContainerFactory.cs deleted file mode 100644 index 2bfb525..0000000 --- a/Hyperbar.Widget/WidgetContainerFactory.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hyperbar.Widget; - -public class WidgetContainerFactory(IServiceFactory factory) : - IFactory -{ - public WidgetContainerViewModel? Create(IWidgetHost value) - { - return factory.Create(value.Configuration.Id); - } -} diff --git a/Hyperbar.Widget/WidgetContainerViewModel.cs b/Hyperbar.Widget/WidgetContainerViewModel.cs deleted file mode 100644 index 5f198ce..0000000 --- a/Hyperbar.Widget/WidgetContainerViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ - -using CommunityToolkit.Mvvm.ComponentModel; - -namespace Hyperbar.Widget; - -[NotificationHandler(nameof(WidgetContainerViewModel))] -public partial class WidgetContainerViewModel(ITemplateFactory templateFactory, - IServiceFactory serviceFactory, - IMediator mediator, - IDisposer disposer, - Guid id) : - ObservableCollectionViewModel(serviceFactory, mediator, disposer), - ITemplatedViewModel -{ - [ObservableProperty] - private Guid id = id; - - public ITemplateFactory TemplateFactory => templateFactory; -} \ No newline at end of file diff --git a/Hyperbar.Widget/WidgetHostHandler.cs b/Hyperbar.Widget/WidgetHostHandler.cs index bcd112e..e8324a7 100644 --- a/Hyperbar.Widget/WidgetHostHandler.cs +++ b/Hyperbar.Widget/WidgetHostHandler.cs @@ -11,13 +11,10 @@ public class WidgetHostHandler(IMediator mediator) : { if (notification.Value is IWidgetHost host) { - if (host.Services.GetRequiredService>() is { } factory) + if (host.Services.GetService() is IWidgetViewModel viewModel) { - if (factory.Create(host) is WidgetContainerViewModel containerViewModel) - { - await mediator.PublishAsync(new Created(containerViewModel), - nameof(WidgetBarViewModel), cancellationToken); - } + await mediator.PublishAsync(new Created(viewModel), + nameof(WidgetViewModel), cancellationToken); } } } diff --git a/Hyperbar.Widget/WidgetViewModelEnumerator.cs b/Hyperbar.Widget/WidgetViewModelEnumerator.cs index d3ac785..34777a1 100644 --- a/Hyperbar.Widget/WidgetViewModelEnumerator.cs +++ b/Hyperbar.Widget/WidgetViewModelEnumerator.cs @@ -14,7 +14,7 @@ public class WidgetViewModelEnumerator(IWidgetHost host, foreach (IWidgetViewModel viewModel in viewModels) { await mediator.PublishAsync(new Created(viewModel), - nameof(WidgetContainerViewModel), cancellationToken); + nameof(WidgetViewModel), cancellationToken); } } } diff --git a/Hyperbar.Windows/Lifecycles/AppInitializer.cs b/Hyperbar.Windows/Lifecycles/AppInitializer.cs index 77ec1b8..e8f9a97 100644 --- a/Hyperbar.Windows/Lifecycles/AppInitializer.cs +++ b/Hyperbar.Windows/Lifecycles/AppInitializer.cs @@ -5,8 +5,8 @@ using Microsoft.Extensions.DependencyInjection; namespace Hyperbar.Windows; -public class AppInitializer([FromKeyedServices(nameof(WidgetBarViewModel))] WidgetBarView view, - [FromKeyedServices(nameof(WidgetBarViewModel))] WidgetBarViewModel viewModel, +public class AppInitializer([FromKeyedServices(nameof(WidgetViewModel))] WidgetBarView view, + [FromKeyedServices(nameof(WidgetViewModel))] WidgetViewModel viewModel, DesktopBar desktopFlyout, AppConfiguration configuration) : IInitializer