Added messaging pipeline
This commit is contained in:
@@ -1,15 +1,11 @@
|
|||||||
using Hyperbar.Lifecycles;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Hyperbar.Extensions.Contextual;
|
namespace Hyperbar.Widget.Contextual;
|
||||||
|
|
||||||
public class ContextualWidgetBuilder :
|
public class ContextualWidgetBuilder :
|
||||||
IWidgetBuilder
|
IWidgetBuilder
|
||||||
{
|
{
|
||||||
public void Create(IServiceCollection services)
|
public void Create(IServiceCollection services) => services
|
||||||
{
|
|
||||||
services
|
|
||||||
.AddConfiguration<ContextualWidgetConfiguration>()
|
.AddConfiguration<ContextualWidgetConfiguration>()
|
||||||
.AddWidgetTemplate<ContextualWidgetViewModel>();
|
.AddWidgetTemplate<ContextualWidgetViewModel>();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Extensions.Contextual;
|
namespace Hyperbar.Widget.Contextual;
|
||||||
|
|
||||||
public class ContextualWidgetConfiguration
|
public class ContextualWidgetConfiguration
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
using Hyperbar.Lifecycles;
|
namespace Hyperbar.Widget.Contextual;
|
||||||
using Hyperbar.Templates;
|
|
||||||
|
|
||||||
namespace Hyperbar.Extensions.Contextual;
|
public class ContextualWidgetViewModel :
|
||||||
|
WidgetViewModelBase
|
||||||
public class ContextualWidgetViewModel(ITemplateFactory templateFactory) :
|
|
||||||
IWidgetViewModel,
|
|
||||||
ITemplatedViewModel
|
|
||||||
{
|
{
|
||||||
public ITemplateFactory TemplateFactory { get; } = templateFactory;
|
public ContextualWidgetViewModel(ITemplateFactory templateFactory,
|
||||||
|
IServiceFactory serviceFactory) : base(templateFactory, serviceFactory)
|
||||||
|
{
|
||||||
|
Add<WidgetButtonViewModel>();
|
||||||
|
Add<WidgetButtonViewModel>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
||||||
<RootNamespace>Hyperbar.Windows.Contextual</RootNamespace>
|
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
|
||||||
<UseWinUI>true</UseWinUI>
|
|
||||||
<UseRidGraph>true</UseRidGraph>
|
<UseRidGraph>true</UseRidGraph>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.25936-preview" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Hyperbar.Windows.Win32\Hyperbar.Windows.Win32.csproj" />
|
|
||||||
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Hyperbar.Lifecycles;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Hyperbar.Windows.Primary;
|
namespace Hyperbar.Windows.Primary;
|
||||||
@@ -6,10 +5,7 @@ namespace Hyperbar.Windows.Primary;
|
|||||||
public class PrimaryWidgetBuilder :
|
public class PrimaryWidgetBuilder :
|
||||||
IWidgetBuilder
|
IWidgetBuilder
|
||||||
{
|
{
|
||||||
public void Create(IServiceCollection services)
|
public void Create(IServiceCollection services) => services.AddConfiguration<PrimaryWidgetConfiguration>()
|
||||||
{
|
.AddWidgetTemplate<PrimaryWidgetViewModel>();
|
||||||
services.AddConfiguration<PrimaryWidgetConfiguration>()
|
|
||||||
.AddTransient<PrimaryWidgetViewModel>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
using Hyperbar.Lifecycles;
|
namespace Hyperbar.Windows.Primary;
|
||||||
using Hyperbar.Templates;
|
|
||||||
|
|
||||||
namespace Hyperbar.Windows.Primary;
|
|
||||||
|
|
||||||
public class PrimaryWidgetViewModel :
|
public class PrimaryWidgetViewModel :
|
||||||
WidgetViewModelBase
|
WidgetViewModelBase
|
||||||
{
|
{
|
||||||
public PrimaryWidgetViewModel(ITemplateFactory templateFactory) : base(templateFactory)
|
public PrimaryWidgetViewModel(ITemplateFactory templateFactory,
|
||||||
|
IServiceFactory serviceFactory) : base(templateFactory, serviceFactory)
|
||||||
{
|
{
|
||||||
|
;
|
||||||
|
|
||||||
|
Add<WidgetButtonViewModel>("test 1", new Action(() => {
|
||||||
|
|
||||||
|
}));
|
||||||
|
Add<WidgetButtonViewModel>("test 2", new Action(() => { }));
|
||||||
|
Add<WidgetButtonViewModel>("test 4", new Action(() => { }));
|
||||||
|
Add<WidgetButtonViewModel>("test 5", new Action(() => { }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using Hyperbar.Windows.Controls;
|
using Hyperbar.Windows.Controls;
|
||||||
using Hyperbar.Lifecycles;
|
|
||||||
using Hyperbar.Templates;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
using Hyperbar.Widget.Contextual;
|
||||||
|
using Hyperbar.Windows.Primary;
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
@@ -28,29 +28,30 @@ public partial class App :
|
|||||||
})
|
})
|
||||||
.ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
|
services.AddSingleton<IServiceFactory>(provider =>
|
||||||
|
new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
||||||
|
|
||||||
services.AddHostedService<AppService>();
|
services.AddHostedService<AppService>();
|
||||||
|
|
||||||
services.AddTransient<IInitializer, AppInitializer>();
|
services.AddTransient<IInitializer, AppInitializer>();
|
||||||
services.AddTransient<DesktopFlyout>();
|
|
||||||
|
|
||||||
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||||
services.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
services.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
||||||
|
|
||||||
|
services.AddTransient<DesktopFlyout>();
|
||||||
services.AddContentTemplate<CommandViewModel, CommandView>();
|
services.AddContentTemplate<CommandViewModel, CommandView>();
|
||||||
|
|
||||||
//services.AddCommand<ContextualCommandWidgetBuilder>("");
|
services.AddWidget<ContextualWidgetBuilder>();
|
||||||
//services.AddWidget<PrimaryCommandWidgetBuilder>("");
|
services.AddWidget<PrimaryWidgetBuilder>();
|
||||||
|
|
||||||
services.AddTransient(provider =>
|
services.AddTransient(provider =>
|
||||||
{
|
{
|
||||||
static IEnumerable<IWidgetViewModel> Resolve(IServiceProvider services)
|
static IEnumerable<IWidgetViewModel> Resolve(IServiceProvider services)
|
||||||
{
|
{
|
||||||
foreach (IWidgetContext commandContext in services.GetServices<IWidgetContext>())
|
foreach (IWidgetContext widgetContext in services.GetServices<IWidgetContext>())
|
||||||
{
|
{
|
||||||
if (commandContext.ServiceProvider.GetService<IWidgetViewModel>() is
|
if (widgetContext.ServiceProvider.GetService<IWidgetViewModel>() is
|
||||||
IWidgetViewModel commandViewModel)
|
IWidgetViewModel viewModel)
|
||||||
{
|
{
|
||||||
yield return commandViewModel;
|
yield return viewModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Views\WidgetButtonView.xaml" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
@@ -38,6 +41,11 @@
|
|||||||
<ProjectReference Include="..\Hyperbar.Windows.Primary\Hyperbar.Widget.Primary.csproj" />
|
<ProjectReference Include="..\Hyperbar.Windows.Primary\Hyperbar.Widget.Primary.csproj" />
|
||||||
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Views\WidgetButtonView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Hyperbar.Windows.Controls;
|
using Hyperbar.Windows.Controls;
|
||||||
using Hyperbar.Lifecycles;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using Hyperbar.Lifecycles;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Hyperbar.Templates;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace Hyperbar.Windows
|
namespace Hyperbar.Windows
|
||||||
{
|
{
|
||||||
public static class IServiceCollectionExtensions
|
public static class IServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddWidget<TCommandBuilder>(this IServiceCollection services,
|
public static IServiceCollection AddWidget<TCommandBuilder>(this IServiceCollection services)
|
||||||
string key)
|
|
||||||
where TCommandBuilder :
|
where TCommandBuilder :
|
||||||
IWidgetBuilder, new()
|
IWidgetBuilder, new()
|
||||||
{
|
{
|
||||||
@@ -16,6 +13,12 @@ namespace Hyperbar.Windows
|
|||||||
IHost? host = new HostBuilder()
|
IHost? host = new HostBuilder()
|
||||||
.ConfigureServices(isolatedServices =>
|
.ConfigureServices(isolatedServices =>
|
||||||
{
|
{
|
||||||
|
isolatedServices.AddSingleton<IServiceFactory>(provider =>
|
||||||
|
new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
||||||
|
|
||||||
|
isolatedServices.AddTransient<IWidgetView, WidgetView>();
|
||||||
|
isolatedServices.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>();
|
||||||
|
|
||||||
isolatedServices.AddTransient<ITemplateFactory, TemplateFactory>();
|
isolatedServices.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||||
isolatedServices.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
isolatedServices.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
using Hyperbar.Templates;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Hyperbar.Templates;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
using Hyperbar.Lifecycles;
|
namespace Hyperbar.Windows;
|
||||||
using Hyperbar.Templates;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
|
||||||
|
|
||||||
public partial class CommandViewModel :
|
public partial class CommandViewModel :
|
||||||
ObservableCollectionViewModel,
|
ObservableCollectionViewModel<IWidgetViewModel>,
|
||||||
ITemplatedViewModel
|
ITemplatedViewModel
|
||||||
{
|
{
|
||||||
public CommandViewModel(ITemplateFactory templateFactory,
|
public CommandViewModel(ITemplateFactory templateFactory,
|
||||||
IEnumerable<IWidgetViewModel> commands)
|
IServiceFactory serviceFactory,
|
||||||
|
IEnumerable<IWidgetViewModel> widgets) : base(serviceFactory)
|
||||||
{
|
{
|
||||||
TemplateFactory = templateFactory;
|
TemplateFactory = templateFactory;
|
||||||
AddRange(commands);
|
AddRange(widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITemplateFactory TemplateFactory { get; }
|
public ITemplateFactory TemplateFactory { get; }
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="Hyperbar.Windows.WidgetButtonView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<SolidColorBrush x:Key="ButtonBackground" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="ButtonBorderBrush" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="ButtonBorderBrushDisabled" Color="Transparent" />
|
||||||
|
<x:Double x:Key="ButtonWidth">32</x:Double>
|
||||||
|
<x:Double x:Key="ButtonHeight">32</x:Double>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Button
|
||||||
|
Width="{StaticResource ButtonWidth}"
|
||||||
|
Height="{StaticResource ButtonHeight}"
|
||||||
|
Command="{Binding Click}"
|
||||||
|
Content="{Binding Icon}" />
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
|
public sealed partial class WidgetButtonView :
|
||||||
|
UserControl
|
||||||
|
{
|
||||||
|
public WidgetButtonView() => InitializeComponent();
|
||||||
|
}
|
||||||
@@ -3,5 +3,11 @@
|
|||||||
x:Class="Hyperbar.Windows.WidgetView"
|
x:Class="Hyperbar.Windows.WidgetView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Grid />
|
<ItemsControl ItemTemplateSelector="{Binding TemplateFactory}" ItemsSource="{Binding}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Hyperbar.Options;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class ConfigurationWriter<TConfiguration>(string path,
|
public class ConfigurationWriter<TConfiguration>(string path,
|
||||||
string section,
|
string section,
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
namespace Hyperbar.Options
|
|
||||||
{
|
public interface IConfigurationWriter<TConfiguration>
|
||||||
public interface IConfigurationWriter<TConfiguration>
|
|
||||||
where TConfiguration :
|
where TConfiguration :
|
||||||
class, new()
|
class, new()
|
||||||
{
|
{
|
||||||
void Write(Action<TConfiguration> updateDelegate);
|
void Write(Action<TConfiguration> updateDelegate);
|
||||||
|
|
||||||
void Write(TConfiguration value);
|
void Write(TConfiguration value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Hyperbar.Options;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using Hyperbar.Lifecycles;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Hyperbar.Options;
|
|
||||||
using Hyperbar.Templates;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
@@ -67,10 +64,10 @@ public static class IServiceCollectionExtensions
|
|||||||
string key = contentType.Name;
|
string key = contentType.Name;
|
||||||
|
|
||||||
services.AddTransient(typeof(IWidgetViewModel), contentType);
|
services.AddTransient(typeof(IWidgetViewModel), contentType);
|
||||||
services.TryAddTransient(provider => provider.GetService<IWidgetView>()!);
|
services.TryAddTransient(templateType, provider => provider.GetService<IWidgetView>()!);
|
||||||
|
|
||||||
services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType);
|
services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType);
|
||||||
services.TryAddKeyedTransient(templateType, key);
|
services.TryAddKeyedTransient<IWidgetView>(key, (provider, key) => provider.GetService<IWidgetView>()!);
|
||||||
|
|
||||||
services.AddTransient<IContentTemplateDescriptor>(provider => new ContentTemplateDescriptor
|
services.AddTransient<IContentTemplateDescriptor>(provider => new ContentTemplateDescriptor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IServiceFactory
|
||||||
|
{
|
||||||
|
TService Create<TService>(params object?[] parameters);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class ServiceFactory(Func<Type, object?[], object> factory) :
|
||||||
|
IServiceFactory
|
||||||
|
{
|
||||||
|
public TService Create<TService>(params object?[] parameters) =>
|
||||||
|
(TService)factory(typeof(TService), parameters);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class AppService(IEnumerable<IInitializer> initializers) :
|
public class AppService(IEnumerable<IInitializer> initializers) :
|
||||||
IHostedService
|
IHostedService
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IInitializer
|
public interface IInitializer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IWidgetBuilder
|
public interface IWidgetBuilder
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IWidgetContext
|
public interface IWidgetContext
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
using System.Collections.ObjectModel;
|
|
||||||
|
|
||||||
namespace Hyperbar.Lifecycles;
|
|
||||||
|
|
||||||
public class ObservableCollectionViewModel<TItem> :
|
|
||||||
ObservableCollection<TItem>
|
|
||||||
{
|
|
||||||
public void AddRange(IEnumerable<TItem> collection)
|
|
||||||
{
|
|
||||||
foreach (TItem? item in collection)
|
|
||||||
{
|
|
||||||
Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ObservableCollectionViewModel :
|
|
||||||
ObservableCollectionViewModel<object>
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
|
||||||
|
|
||||||
public class WidgetButtonViewModel
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class WidgetContext(IServiceProvider serviceProvider) :
|
public class WidgetContext(IServiceProvider serviceProvider) :
|
||||||
IWidgetContext
|
IWidgetContext
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
using Hyperbar.Templates;
|
|
||||||
|
|
||||||
namespace Hyperbar.Lifecycles;
|
|
||||||
|
|
||||||
public class WidgetViewModelBase(ITemplateFactory templateFactory) :
|
|
||||||
ObservableCollectionViewModel<IWidgetComponentViewModel>,
|
|
||||||
IWidgetViewModel,
|
|
||||||
ITemplatedViewModel
|
|
||||||
{
|
|
||||||
public ITemplateFactory TemplateFactory { get; } = templateFactory;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class CommandClassHandlerWrapper<TRequest, TResponse>
|
||||||
|
where TRequest :
|
||||||
|
class,
|
||||||
|
ICommand<TResponse>
|
||||||
|
{
|
||||||
|
private readonly MessageHandlerDelegate<TRequest, TResponse> handler;
|
||||||
|
|
||||||
|
public CommandClassHandlerWrapper(ICommandHandler<TRequest, TResponse> concreteHandler,
|
||||||
|
IEnumerable<IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours)
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handler = concreteHandler.Handle;
|
||||||
|
|
||||||
|
foreach (IPipelineBehavior<TRequest, TResponse>? pipeline in pipelineBehaviours.Reverse())
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handlerCopy = handler;
|
||||||
|
IPipelineBehavior<TRequest, TResponse> pipelineCopy = pipeline;
|
||||||
|
handler = (TRequest message, CancellationToken cancellationToken) =>
|
||||||
|
pipelineCopy.Handle(message, handlerCopy, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Handle(TRequest request, CancellationToken cancellationToken) => handler(request, cancellationToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ICommand : ICommand<Unit>;
|
||||||
|
|
||||||
|
public interface ICommand<out TResponse> : IMessage;
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ICommandHandler<in TCommand> : ICommandHandler<TCommand, Unit>
|
||||||
|
where TCommand :
|
||||||
|
ICommand<Unit>;
|
||||||
|
|
||||||
|
public interface ICommandHandler<in TCommand, TResponse>
|
||||||
|
where TCommand :
|
||||||
|
ICommand<TResponse>
|
||||||
|
{
|
||||||
|
ValueTask<TResponse> Handle(TCommand command,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IMediator
|
||||||
|
{
|
||||||
|
ValueTask Publish<TNotification>(TNotification notification,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification;
|
||||||
|
|
||||||
|
ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
ValueTask<TResponse> Send<TResponse>(ICommand<TResponse> command,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
ValueTask<TResponse> Send<TResponse>(IQuery<TResponse> query,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
ValueTask<object?> Send(object message, CancellationToken
|
||||||
|
cancellationToken = default);
|
||||||
|
|
||||||
|
void Subscribe(object subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IMessage;
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface INotification : IMessage;
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface INotificationHandler<in TNotification>
|
||||||
|
where TNotification :
|
||||||
|
INotification
|
||||||
|
{
|
||||||
|
ValueTask Handle(TNotification notification,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IPipelineBehavior<TMessage, TResponse>
|
||||||
|
where TMessage :
|
||||||
|
notnull,
|
||||||
|
IMessage
|
||||||
|
{
|
||||||
|
ValueTask<TResponse> Handle(TMessage message,
|
||||||
|
MessageHandlerDelegate<TMessage, TResponse> next,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IQuery<out TResponse> : IMessage;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IQueryHandler<in TQuery, TResponse>
|
||||||
|
where TQuery :
|
||||||
|
IQuery<TResponse>
|
||||||
|
{
|
||||||
|
ValueTask<TResponse> Handle(TQuery query,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IRequest<out TResponse> : IMessage;
|
||||||
|
|
||||||
|
public interface IRequest : IRequest<Unit>;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IRequestHandler<in TRequest, TResponse>
|
||||||
|
where TRequest :
|
||||||
|
IRequest<TResponse>
|
||||||
|
{
|
||||||
|
ValueTask<TResponse> Handle(TRequest request,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IRequestHandler<in TRequest> :
|
||||||
|
IRequestHandler<TRequest, Unit>
|
||||||
|
where TRequest :
|
||||||
|
IRequest<Unit>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class Mediator(IServiceProvider provider) :
|
||||||
|
IMediator
|
||||||
|
{
|
||||||
|
private readonly ConditionalWeakTable<Type, dynamic> handlers = [];
|
||||||
|
|
||||||
|
public ValueTask Publish<TNotification>(TNotification notification,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification
|
||||||
|
{
|
||||||
|
List<INotificationHandler<TNotification>> handlers =
|
||||||
|
provider.GetServices<INotificationHandler<TNotification>>().ToList();
|
||||||
|
|
||||||
|
foreach (KeyValuePair<Type, dynamic> handler in this.handlers)
|
||||||
|
{
|
||||||
|
if (handler.Key == typeof(TNotification))
|
||||||
|
{
|
||||||
|
handlers.Add(handler.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handlers.Count == 0)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
else if (handlers.Count == 1)
|
||||||
|
{
|
||||||
|
return handlers[0].Handle(notification, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
dynamic? handler = provider.GetService(typeof(RequestClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(request.GetType(), typeof(TResponse)));
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)request, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Send<TResponse>(ICommand<TResponse> command,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
dynamic? handler = provider.GetService(typeof(CommandClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(command.GetType(), typeof(TResponse)));
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)command, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Send<TResponse>(IQuery<TResponse> query,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
dynamic? handler = provider.GetService(typeof(QueryClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(query.GetType(), typeof(TResponse)));
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)query, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<object?> Send(object message,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (message.GetType().GetInterface(typeof(IRequest<>).Name) is { } requestType)
|
||||||
|
{
|
||||||
|
if (requestType.GetGenericArguments() is { Length: 1 } arguments)
|
||||||
|
{
|
||||||
|
Type responseType = arguments[0];
|
||||||
|
|
||||||
|
dynamic? handler = provider.GetService(typeof(RequestClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(message.GetType(), responseType));
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)message, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.GetType().GetInterface(typeof(ICommand<>).Name) is { } commandType)
|
||||||
|
{
|
||||||
|
if (commandType.GetGenericArguments() is { Length: 1 } arguments)
|
||||||
|
{
|
||||||
|
Type responseType = arguments[0];
|
||||||
|
|
||||||
|
dynamic? handler = provider.GetService(typeof(CommandClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(message.GetType(), responseType));
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)message, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.GetType().GetInterface(typeof(IQuery<>).Name) is { } queryType)
|
||||||
|
{
|
||||||
|
if (queryType.GetGenericArguments() is { Length: 1 } arguments)
|
||||||
|
{
|
||||||
|
Type responseType = arguments[0];
|
||||||
|
|
||||||
|
dynamic? handler = provider.GetService(typeof(QueryClassHandlerWrapper<,>)
|
||||||
|
.MakeGenericType(message.GetType(), responseType));
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
return handler.Handle((dynamic)message, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Subscribe(object subject)
|
||||||
|
{
|
||||||
|
Type[] interfaceTypes = subject.GetType().GetInterfaces();
|
||||||
|
foreach (Type interfaceType in interfaceTypes.Where(x => x.IsGenericType))
|
||||||
|
{
|
||||||
|
if (interfaceType.GetGenericTypeDefinition() == typeof(INotificationHandler<>))
|
||||||
|
{
|
||||||
|
if (interfaceType.GetGenericArguments() is { Length: 1 } arguments)
|
||||||
|
{
|
||||||
|
Type notificationType = arguments[0];
|
||||||
|
handlers.Add(notificationType, subject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public delegate ValueTask<TResponse> MessageHandlerDelegate<TMessage, TResponse>(TMessage message,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
where TMessage :
|
||||||
|
notnull,
|
||||||
|
IMessage;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class QueryClassHandlerWrapper<TRequest, TResponse>
|
||||||
|
where TRequest :
|
||||||
|
class,
|
||||||
|
IQuery<TResponse>
|
||||||
|
{
|
||||||
|
private readonly MessageHandlerDelegate<TRequest, TResponse> handler;
|
||||||
|
|
||||||
|
public QueryClassHandlerWrapper(IQueryHandler<TRequest, TResponse> concreteHandler,
|
||||||
|
IEnumerable<IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours)
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handler = concreteHandler.Handle;
|
||||||
|
|
||||||
|
foreach (IPipelineBehavior<TRequest, TResponse>? pipeline in pipelineBehaviours.Reverse())
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handlerCopy = handler;
|
||||||
|
IPipelineBehavior<TRequest, TResponse> pipelineCopy = pipeline;
|
||||||
|
handler = (TRequest message, CancellationToken cancellationToken) =>
|
||||||
|
pipelineCopy.Handle(message, handlerCopy, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Handle(TRequest request, CancellationToken cancellationToken) =>
|
||||||
|
handler(request, cancellationToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class RequestClassHandlerWrapper<TRequest, TResponse>
|
||||||
|
where TRequest :
|
||||||
|
class,
|
||||||
|
IRequest<TResponse>
|
||||||
|
{
|
||||||
|
private readonly MessageHandlerDelegate<TRequest, TResponse> handler;
|
||||||
|
|
||||||
|
public RequestClassHandlerWrapper(IRequestHandler<TRequest, TResponse> concreteHandler,
|
||||||
|
IEnumerable<IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours)
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handler = concreteHandler.Handle;
|
||||||
|
foreach (IPipelineBehavior<TRequest, TResponse>? pipeline in pipelineBehaviours.Reverse())
|
||||||
|
{
|
||||||
|
MessageHandlerDelegate<TRequest, TResponse> handlerCopy = handler;
|
||||||
|
IPipelineBehavior<TRequest, TResponse> pipelineCopy = pipeline;
|
||||||
|
|
||||||
|
handler = (TRequest message, CancellationToken cancellationToken) =>
|
||||||
|
pipelineCopy.Handle(message, handlerCopy, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<TResponse> Handle(TRequest request, CancellationToken cancellationToken) => handler(request, cancellationToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public readonly struct Unit :
|
||||||
|
IEquatable<Unit>,
|
||||||
|
IComparable<Unit>,
|
||||||
|
IComparable
|
||||||
|
{
|
||||||
|
private static readonly Unit value = new();
|
||||||
|
|
||||||
|
public static ref readonly Unit Value => ref value;
|
||||||
|
|
||||||
|
public static ValueTask<Unit> ValueTask => new(value);
|
||||||
|
|
||||||
|
public int CompareTo(Unit other) => 0;
|
||||||
|
|
||||||
|
int IComparable.CompareTo(object? obj) => 0;
|
||||||
|
|
||||||
|
public override int GetHashCode() => 0;
|
||||||
|
|
||||||
|
public bool Equals(Unit other) => true;
|
||||||
|
|
||||||
|
public override bool Equals(object? obj) => obj is Unit;
|
||||||
|
|
||||||
|
public static bool operator ==(Unit _, Unit __) => true;
|
||||||
|
|
||||||
|
public static bool operator !=(Unit _, Unit __) => false;
|
||||||
|
|
||||||
|
public override string ToString() => "()";
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Templates;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public record ContentTemplateDescriptor :
|
public record ContentTemplateDescriptor :
|
||||||
IContentTemplateDescriptor
|
IContentTemplateDescriptor
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Templates;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IContentTemplateDescriptor
|
public interface IContentTemplateDescriptor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Templates;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface ITemplateFactory
|
public interface ITemplateFactory
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Templates;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface ITemplatedViewModel
|
public interface ITemplatedViewModel
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IWidgetComponentViewModel
|
public interface IWidgetComponentViewModel
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Hyperbar.Lifecycles;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface IWidgetViewModel
|
public interface IWidgetViewModel
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class ObservableCollectionViewModel<TItem>(IServiceFactory serviceFactory) :
|
||||||
|
ObservableCollection<TItem>
|
||||||
|
{
|
||||||
|
public TItem Add()
|
||||||
|
{
|
||||||
|
TItem? item = serviceFactory.Create<TItem>();
|
||||||
|
|
||||||
|
Add(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TItem Add<T>(params object?[] parameters)
|
||||||
|
where T : TItem
|
||||||
|
{
|
||||||
|
T? item = serviceFactory.Create<T>(parameters);
|
||||||
|
Add(item);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TItem Add<T>()
|
||||||
|
where T :
|
||||||
|
TItem
|
||||||
|
{
|
||||||
|
T? item = serviceFactory.Create<T>();
|
||||||
|
Add(item);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRange(IEnumerable<TItem> items)
|
||||||
|
{
|
||||||
|
foreach (TItem? item in items)
|
||||||
|
{
|
||||||
|
Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ObservableCollectionViewModel(IServiceFactory serviceFactory) :
|
||||||
|
ObservableCollectionViewModel<object>(serviceFactory)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public partial class WidgetButtonViewModel :
|
||||||
|
WidgetComponentViewModelBase
|
||||||
|
{
|
||||||
|
[ObservableProperty]
|
||||||
|
private string? icon;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private IRelayCommand? click;
|
||||||
|
|
||||||
|
public WidgetButtonViewModel(ITemplateFactory templateFactory,
|
||||||
|
string? icon = null,
|
||||||
|
Action? action = null) : base(templateFactory)
|
||||||
|
{
|
||||||
|
this.icon = icon;
|
||||||
|
if (action is not null)
|
||||||
|
{
|
||||||
|
click = new RelayCommand(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public partial class WidgetComponentViewModelBase(ITemplateFactory templateFactory) :
|
||||||
|
ObservableObject,
|
||||||
|
IWidgetComponentViewModel,
|
||||||
|
ITemplatedViewModel
|
||||||
|
{
|
||||||
|
public ITemplateFactory TemplateFactory => templateFactory;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class WidgetViewModelBase(ITemplateFactory templateFactory,
|
||||||
|
IServiceFactory serviceFactory) :
|
||||||
|
ObservableCollectionViewModel<IWidgetComponentViewModel>(serviceFactory),
|
||||||
|
IWidgetViewModel,
|
||||||
|
ITemplatedViewModel
|
||||||
|
{
|
||||||
|
public ITemplateFactory TemplateFactory => templateFactory;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user