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

This commit is contained in:
TheXamlGuy
2024-01-30 22:30:08 +00:00
parent 215ff81653
commit 858a23c28d
14 changed files with 139 additions and 180 deletions
+11 -7
View File
@@ -6,14 +6,18 @@ public interface IWidgetBuilder
{
IWidgetHost Build();
IWidgetBuilder Configuration<TConfiguration>(Action<TConfiguration> configurationDelegate)
where TConfiguration :
WidgetConfiguration,
new();
IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate);
}
public interface IWidgetBuilder<TConfiguration> :
IWidgetBuilder
where TConfiguration :
WidgetConfiguration,
new()
{
IWidgetBuilder UseViewModel<TViewModel>()
where TViewModel :
IWidgetViewModel;
IWidgetBuilder UseViewModelTemplate<TViewModel, TTemplate>()
where TViewModel :
IWidgetViewModel;
}
+3 -3
View File
@@ -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<WidgetContainerViewModel>(serviceFactory, mediator, disposer),
ObservableCollectionViewModel<IWidgetViewModel>(serviceFactory, mediator, disposer),
ITemplatedViewModel
{
public ITemplateFactory TemplateFactory => templateFactory;
+62 -34
View File
@@ -5,47 +5,63 @@ using System.Reflection;
namespace Hyperbar.Widget;
public class WidgetBuilder<TConfiguration>(TConfiguration configuration) :
IWidgetBuilder<TConfiguration>
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<IWidgetHost, WidgetHost>();
services.AddScoped<IServiceFactory>(provider =>
new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
services.AddScoped<IMediator, Mediator>();
services.AddScoped<IDisposer, Disposer>();
services.AddSingleton<IValue<WidgetAvailability>, Value<WidgetAvailability>>();
});
}
public static IWidgetBuilder Create() => new WidgetBuilder();
public IWidgetBuilder Configuration<TConfiguration>(Action<TConfiguration> 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<IWidgetHost, WidgetHost>();
services.AddScoped<IServiceFactory>(provider =>
new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
services.AddScoped<IMediator, Mediator>();
services.AddScoped<IDisposer, Disposer>();
services.AddSingleton<IValue<WidgetAvailability>,
Value<WidgetAvailability>>();
services.AddHandler<WidgetConfigurationHandler>();
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name,
configuration: configuration);
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name, configuration: configuration);
services.AddConfiguration(configuration);
});
public static IWidgetBuilder Configure(Action<TConfiguration> configurationDelegate)
{
TConfiguration configuration = new();
configurationDelegate(configuration);
return new WidgetBuilder<TConfiguration>(configuration);
return this;
}
public IWidgetBuilder UseViewModelTemplate<TWidgetContent, TWidgetTemplate>()
where TWidgetContent :
IWidgetViewModel
{
hostBuilder.ConfigureServices(services =>
{
services.AddWidgetTemplate<TWidgetContent, TWidgetTemplate>();
});
return this;
}
public IWidgetHost Build()
{
IHost host = hostBuilder.Build();
@@ -54,7 +70,19 @@ public class WidgetBuilder<TConfiguration>(TConfiguration configuration) :
public IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate)
{
hostBuilder.ConfigureServices(configureDelegate.Invoke);
hostBuilder.ConfigureServices(configureDelegate);
return this;
}
}
public IWidgetBuilder UseViewModel<TViewModel>()
where TViewModel :
IWidgetViewModel
{
hostBuilder.ConfigureServices(services =>
{
services.AddWidgetTemplate<TViewModel>();
});
return this;
}
}
-10
View File
@@ -1,10 +0,0 @@
namespace Hyperbar.Widget;
public class WidgetContainerFactory(IServiceFactory factory) :
IFactory<IWidgetHost, WidgetContainerViewModel?>
{
public WidgetContainerViewModel? Create(IWidgetHost value)
{
return factory.Create<WidgetContainerViewModel>(value.Configuration.Id);
}
}
@@ -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<IWidgetViewModel>(serviceFactory, mediator, disposer),
ITemplatedViewModel
{
[ObservableProperty]
private Guid id = id;
public ITemplateFactory TemplateFactory => templateFactory;
}
+3 -6
View File
@@ -11,13 +11,10 @@ public class WidgetHostHandler(IMediator mediator) :
{
if (notification.Value is IWidgetHost host)
{
if (host.Services.GetRequiredService<IFactory<IWidgetHost, WidgetContainerViewModel?>>() is { } factory)
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
{
if (factory.Create(host) is WidgetContainerViewModel containerViewModel)
{
await mediator.PublishAsync(new Created<WidgetContainerViewModel>(containerViewModel),
nameof(WidgetBarViewModel), cancellationToken);
}
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
nameof(WidgetViewModel), cancellationToken);
}
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ public class WidgetViewModelEnumerator(IWidgetHost host,
foreach (IWidgetViewModel viewModel in viewModels)
{
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
nameof(WidgetContainerViewModel), cancellationToken);
nameof(WidgetViewModel), cancellationToken);
}
}
}