Rip out Microsoft's configuration and replace because it simply doesn't support polymorphism.... we are getting advanced boys!!!

This commit is contained in:
TheXamlGuy
2024-01-09 20:32:07 +00:00
parent e72d997563
commit 05b404d504
19 changed files with 247 additions and 135 deletions
@@ -3,6 +3,7 @@ using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Controls.Primitives;
using Hyperbar.Windows.UI; using Hyperbar.Windows.UI;
using Hyperbar.Windows.Interop; using Hyperbar.Windows.Interop;
using Windows.Foundation;
namespace Hyperbar.Windows.Controls; namespace Hyperbar.Windows.Controls;
@@ -38,7 +39,7 @@ internal class DesktopFlyoutHost : Window
return; return;
} }
// presenter.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); presenter.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
double height = presenter.DesiredSize.Height; double height = presenter.DesiredSize.Height;
double width = presenter.DesiredSize.Width; double width = presenter.DesiredSize.Width;
@@ -12,7 +12,7 @@ public class DesktopFlyoutPresenter :
typeof(DesktopFlyoutPresenterTemplateSettings), typeof(DesktopFlyoutPresenter), typeof(DesktopFlyoutPresenterTemplateSettings), typeof(DesktopFlyoutPresenter),
new PropertyMetadata(null)); new PropertyMetadata(null));
internal new DesktopFlyout Parent; internal new DesktopFlyout? Parent;
public DesktopFlyoutPresenter() public DesktopFlyoutPresenter()
{ {
@@ -5,21 +5,22 @@
xmlns:controls="using:Hyperbar.Windows.Controls"> xmlns:controls="using:Hyperbar.Windows.Controls">
<ResourceDictionary.ThemeDictionaries> <ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default"> <ResourceDictionary x:Key="Default">
<StaticResource x:Key="CommandBarFlyoutBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" />
<StaticResource x:Key="CommandBarFlyoutForeground" ResourceKey="TextFillColorPrimaryBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="CommandBarFlyoutBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" />
</ResourceDictionary> </ResourceDictionary>
<ResourceDictionary x:Key="Light"> <ResourceDictionary x:Key="Light">
<StaticResource x:Key="CommandBarFlyoutBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" />
<StaticResource x:Key="CommandBarFlyoutForeground" ResourceKey="TextFillColorPrimaryBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="CommandBarFlyoutBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" /> <StaticResource x:Key="DesktopFlyoutPresenterBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" />
</ResourceDictionary> </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries> </ResourceDictionary.ThemeDictionaries>
<Thickness x:Key="DesktopFlyoutPresenterBorderThemeThickness">1</Thickness>
<Style TargetType="controls:DesktopFlyoutPresenter"> <Style TargetType="controls:DesktopFlyoutPresenter">
<Setter Property="Background" Value="{ThemeResource CommandBarFlyoutBackground}" /> <Setter Property="Background" Value="{ThemeResource DesktopFlyoutPresenterBackground}" />
<Setter Property="Foreground" Value="{ThemeResource CommandBarFlyoutForeground}" /> <Setter Property="Foreground" Value="{ThemeResource DesktopFlyoutPresenterForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource CommandBarFlyoutBorderBrush}" /> <Setter Property="BorderBrush" Value="{ThemeResource DesktopFlyoutPresenterBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource CommandBarFlyoutBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{ThemeResource DesktopFlyoutPresenterBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{ThemeResource OverlayCornerRadius}" /> <Setter Property="CornerRadius" Value="{ThemeResource OverlayCornerRadius}" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
@@ -29,9 +30,9 @@
x:Name="BackgroundElement" x:Name="BackgroundElement"
Height="48" Height="48"
MinWidth="40" MinWidth="40"
Margin="24" Margin="16"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge" BackgroundSizing="OuterBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" CornerRadius="{TemplateBinding CornerRadius}"
@@ -42,7 +43,8 @@
</TransitionCollection> </TransitionCollection>
</Border.Transitions> </Border.Transitions>
<ContentControl <ContentControl
Margin="{TemplateBinding Padding}" Height="40"
Margin="4"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
+1 -2
View File
@@ -24,8 +24,7 @@ public class VirtualKeyboard :
91 // LeftWindows 91 // LeftWindows
]; ];
public void Send(int key, public void Send(int key, params int[] modifierKeys)
params int[] modifierKeys)
{ {
foreach (int modiferKey in modifierKeys) foreach (int modiferKey in modifierKeys)
{ {
@@ -1,5 +1,10 @@
namespace Hyperbar.Windows.Primary; using System.Text.Json.Serialization;
public interface IPrimaryCommandConfiguration namespace Hyperbar.Windows.Primary;
[JsonDerivedType(typeof(KeyAcceleratorCommandConfiguration), typeDiscriminator: "KeyAcceleratorCommand")]
[JsonDerivedType(typeof(ProcessCommandConfiguration), typeDiscriminator: "ProcessCommand")]
public class PrimaryCommandConfiguration
{ {
public string? Icon { get; set; }
} }
@@ -1,11 +1,9 @@
namespace Hyperbar.Windows.Primary; namespace Hyperbar.Windows.Primary;
public class KeyAcceleratorCommandConfiguration : public class KeyAcceleratorCommandConfiguration :
IPrimaryCommandConfiguration PrimaryCommandConfiguration
{ {
public string? Icon { get; set; } public int Key { get; set; }
public string? Key { get; set; } public int[]? Modifiers { get; set; }
public string[]? Modifiers { get; set; }
} }
@@ -1,10 +1,10 @@
namespace Hyperbar.Windows.Primary; namespace Hyperbar.Windows.Primary;
public class PrimaryWidgetConfiguration : public class PrimaryWidgetConfiguration :
List<KeyAcceleratorCommandConfiguration> List<PrimaryCommandConfiguration>
{ {
public static PrimaryWidgetConfiguration Defaults => new() public static PrimaryWidgetConfiguration Defaults => new()
{ {
new KeyAcceleratorCommandConfiguration { Icon = "\uE720", Key = "Test", Modifiers = ["Test", "Test"] } new KeyAcceleratorCommandConfiguration { Icon = "\uE720", Key = 91, Modifiers = [] }
}; };
} }
@@ -7,7 +7,7 @@ public class PrimaryWidgetProvider :
IWidgetProvider IWidgetProvider
{ {
public void Create(HostBuilderContext comtext, IServiceCollection services) => public void Create(HostBuilderContext comtext, IServiceCollection services) =>
services.AddConfiguration< PrimaryWidgetConfiguration>(comtext.Configuration.GetSection(nameof(PrimaryWidgetConfiguration))) services.AddConfiguration<PrimaryWidgetConfiguration>()
.AddHandler<WidgetComponentMapping>() .AddHandler<WidgetComponentMapping>()
.AddHandler<PrimaryWidgetConfigurationChangedHandler>() .AddHandler<PrimaryWidgetConfigurationChangedHandler>()
.AddWidgetTemplate<PrimaryWidgetViewModel>(); .AddWidgetTemplate<PrimaryWidgetViewModel>();
@@ -0,0 +1,7 @@
namespace Hyperbar.Windows.Primary;
public class ProcessCommandConfiguration :
PrimaryCommandConfiguration
{
public string? Path { get; set; }
}
@@ -1,5 +1,4 @@
namespace Hyperbar.Windows.Primary;
namespace Hyperbar.Windows.Primary;
public class WidgetComponentMapping(PrimaryWidgetConfiguration configuration, public class WidgetComponentMapping(PrimaryWidgetConfiguration configuration,
IServiceFactory service, IServiceFactory service,
@@ -8,12 +7,18 @@ public class WidgetComponentMapping(PrimaryWidgetConfiguration configuration,
{ {
public IEnumerable<IWidgetComponentViewModel> Handle() public IEnumerable<IWidgetComponentViewModel> Handle()
{ {
foreach (IPrimaryCommandConfiguration item in configuration) foreach (var item in configuration)
{ {
if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommand) if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommandConfiguration)
{ {
yield return service.Create<WidgetButtonViewModel>(keyAcceleratorCommand.Icon, new Action(async () => yield return service.Create<WidgetButtonViewModel>(keyAcceleratorCommandConfiguration.Icon, new Action(async () =>
await mediator.SendAsync(new KeyAcceleratorCommand(VirtualKey.LeftWindows)))); await mediator.SendAsync(new KeyAcceleratorRequest((VirtualKey)keyAcceleratorCommandConfiguration.Key,
keyAcceleratorCommandConfiguration.Modifiers?.Select(modifier => (VirtualKey)modifier).ToArray()))));
}
if (item is ProcessCommandConfiguration processCommandConfiguration)
{
} }
} }
} }
+3 -2
View File
@@ -4,8 +4,10 @@ using Hyperbar.Windows.Primary;
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.Extensions.Options;
using Microsoft.UI.Dispatching; using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using System.Text.Json;
namespace Hyperbar.Windows; namespace Hyperbar.Windows;
@@ -18,8 +20,7 @@ public partial class App :
{ {
base.OnLaunched(args); base.OnLaunched(args);
var context = new DispatcherQueueSynchronizationContext( DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread());
DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context); SynchronizationContext.SetSynchronizationContext(context);
IHost? host = Host.CreateDefaultBuilder() IHost? host = Host.CreateDefaultBuilder()
@@ -36,7 +36,7 @@ namespace Hyperbar.Windows
isolatedServices.AddSingleton<IMediator, Mediator>(); isolatedServices.AddSingleton<IMediator, Mediator>();
isolatedServices.AddHandler<KeyAcceleratorHandler>(); isolatedServices.AddHandler<KeyAcceleratorHandler>();
isolatedServices.AddHandler<ProcesssAcceleratorHandler>();
isolatedServices.AddTransient<IWidgetView, WidgetView>(); isolatedServices.AddTransient<IWidgetView, WidgetView>();
isolatedServices.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>(); isolatedServices.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>();
@@ -1,14 +1,26 @@
using Hyperbar.Windows.Interop; using Hyperbar.Windows.Interop;
using System.Diagnostics;
namespace Hyperbar.Windows; namespace Hyperbar.Windows;
public class KeyAcceleratorHandler(IVirtualKeyboard virtualKeyboard) : public class KeyAcceleratorHandler(IVirtualKeyboard virtualKeyboard) :
IRequestHandler<KeyAcceleratorCommand> IRequestHandler<KeyAcceleratorRequest>
{ {
public ValueTask<Unit> Handle(KeyAcceleratorCommand command, public ValueTask<Unit> Handle(KeyAcceleratorRequest request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
virtualKeyboard.Send((int)command.Key); virtualKeyboard.Send((int)request.Key, request.Modifiers?.Select(modifier => (int)modifier).ToArray() ?? []);
return default;
}
}
public class ProcesssAcceleratorHandler :
IRequestHandler<ProcessRequest>
{
public ValueTask<Unit> Handle(ProcessRequest request,
CancellationToken cancellationToken)
{
Process.Start(request.Process);
return default; return default;
} }
} }
+4 -3
View File
@@ -10,13 +10,14 @@
<SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="Transparent" /> <SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="Transparent" />
<SolidColorBrush x:Key="ButtonBorderBrushDisabled" Color="Transparent" /> <SolidColorBrush x:Key="ButtonBorderBrushDisabled" Color="Transparent" />
<Thickness x:Key="ButtonPadding">0</Thickness> <Thickness x:Key="ButtonPadding">0</Thickness>
<x:Double x:Key="ButtonWidth">32</x:Double> <x:Double x:Key="ButtonWidth">40</x:Double>
<x:Double x:Key="ButtonHeight">32</x:Double> <x:Double x:Key="ButtonHeight">40</x:Double>
</UserControl.Resources> </UserControl.Resources>
<Button <Button
Width="{StaticResource ButtonWidth}" Width="{StaticResource ButtonWidth}"
Height="{StaticResource ButtonHeight}" Height="{StaticResource ButtonHeight}"
Padding="0" Padding="{StaticResource ButtonPadding}"
FontSize="16"
Command="{Binding Click}" Command="{Binding Click}"
Content="{Binding Icon}" Content="{Binding Icon}"
FontFamily="{StaticResource SymbolThemeFontFamily}" /> FontFamily="{StaticResource SymbolThemeFontFamily}" />
+10 -1
View File
@@ -1,4 +1,5 @@
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
namespace Hyperbar.Windows; namespace Hyperbar.Windows;
@@ -6,5 +7,13 @@ public sealed partial class WidgetView :
UserControl, UserControl,
IWidgetView IWidgetView
{ {
public WidgetView() => InitializeComponent(); public WidgetView()
{
InitializeComponent();
}
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
base.OnKeyDown(e);
}
} }
@@ -1,5 +1,5 @@
namespace Hyperbar; namespace Hyperbar;
public record KeyAcceleratorCommand(VirtualKey Key, public record KeyAcceleratorRequest(VirtualKey Key,
VirtualKey[]? Modifiers = null) : VirtualKey[]? Modifiers = null) :
IRequest; IRequest;
+3
View File
@@ -0,0 +1,3 @@
namespace Hyperbar;
public record ProcessRequest(string Process) : IRequest;
+56 -1
View File
@@ -4,7 +4,62 @@ using System.Text.Json.Serialization;
namespace Hyperbar; namespace Hyperbar;
public class ConfigurationWriter<TConfiguration>(string path, public interface IConfigurationReader<TConfiguration>
where TConfiguration :
class, new()
{
TConfiguration Read();
}
public class ConfigurationReader<TConfiguration>(string path,
string section,
JsonSerializerOptions? serializerOptions = null) :
IConfigurationReader<TConfiguration>
where TConfiguration :
class, new()
{
private static readonly Func<JsonSerializerOptions> defaultSerializerOptions = new(() =>
{
return new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Converters =
{
new JsonStringEnumConverter()
}
};
});
public TConfiguration Read()
{
if ((TryGet(out TConfiguration? value) ? value : new TConfiguration()) is TConfiguration configuration)
{
return configuration;
}
return new TConfiguration();
}
private bool TryGet(out TConfiguration? value)
{
if (File.Exists(path))
{
byte[] jsonContent = File.ReadAllBytes(path);
using JsonDocument jsonDocument = JsonDocument.Parse(jsonContent);
if (jsonDocument.RootElement.TryGetProperty(section, out JsonElement sectionValue))
{
value = JsonSerializer.Deserialize<TConfiguration>(sectionValue.ToString(), serializerOptions ?? defaultSerializerOptions());
return true;
}
}
value = default;
return false;
}
}
public class ConfigurationWriter<TConfiguration>(string path,
string section, string section,
JsonSerializerOptions? serializerOptions = null) : JsonSerializerOptions? serializerOptions = null) :
IConfigurationWriter<TConfiguration> IConfigurationWriter<TConfiguration>
@@ -3,15 +3,113 @@ 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;
using Microsoft.Extensions.Options;
using System.Text.Json; using System.Text.Json;
namespace Hyperbar; namespace Hyperbar;
public static class IServiceCollectionExtensions public static class IServiceCollectionExtensions
{ {
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services)
where TConfiguration :
class, new()
{
return services.AddConfiguration<TConfiguration>(typeof(TConfiguration).Name, "Settings.json", null);
}
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services,
IConfiguration configuration,
TConfiguration? defaults = null)
where TConfiguration :
class, new()
{
return services.AddConfiguration(typeof(TConfiguration).Name, "Settings.json", defaults);
}
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services,
string section,
string path = "Settings.json",
TConfiguration? defaults = null,
Action<JsonSerializerOptions>? serializerDelegate = null)
where TConfiguration :
class, new()
{
services.AddTransient(provider => provider.GetRequiredService<IConfigurationReader<TConfiguration>>().Read());
services.AddSingleton<IConfigurationReader<TConfiguration>>(provider =>
{
string? jsonFilePath = null;
if (provider.GetService<IHostEnvironment>() is IHostEnvironment hostEnvironment)
{
IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider;
IFileInfo fileInfo = fileProvider.GetFileInfo(path);
jsonFilePath = fileInfo.PhysicalPath;
}
jsonFilePath ??= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
JsonSerializerOptions? defaultSerializer = null;
if (serializerDelegate is not null)
{
defaultSerializer = new JsonSerializerOptions();
serializerDelegate.Invoke(defaultSerializer);
}
return new ConfigurationReader<TConfiguration>(jsonFilePath, section, defaultSerializer);
});
services.AddSingleton<IConfigurationWriter<TConfiguration>>(provider =>
{
string? jsonFilePath = null;
if (provider.GetService<IHostEnvironment>() is IHostEnvironment hostEnvironment)
{
IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider;
IFileInfo fileInfo = fileProvider.GetFileInfo(path);
jsonFilePath = fileInfo.PhysicalPath;
}
jsonFilePath ??= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
JsonSerializerOptions? defaultSerializer = null;
if (serializerDelegate is not null)
{
defaultSerializer = new JsonSerializerOptions();
serializerDelegate.Invoke(defaultSerializer);
}
return new ConfigurationWriter<TConfiguration>(jsonFilePath, section, defaultSerializer);
});
services.AddTransient(provider => new DefaultConfiguration<TConfiguration>(defaults));
services.AddTransient<IInitializer, ConfigurationInitializer<TConfiguration>>();
services.AddTransient<IWritableConfiguration<TConfiguration>, WritableConfiguration<TConfiguration>>();
return services;
}
public static IServiceCollection AddContentTemplate<TContent, TTemplate>(this IServiceCollection services,
object? key = null)
{
Type contentType = typeof(TContent);
Type templateType = typeof(TTemplate);
key ??= contentType.Name;
services.AddTransient(contentType);
services.TryAddTransient(templateType);
services.AddKeyedTransient(contentType, key);
services.AddKeyedTransient(templateType, key);
services.AddTransient<IContentTemplateDescriptor>(provider => new ContentTemplateDescriptor { ContentType = contentType, TemplateType = templateType, Key = key });
return services;
}
public static IServiceCollection AddHandler<THandler>(this IServiceCollection services, public static IServiceCollection AddHandler<THandler>(this IServiceCollection services,
ServiceLifetime lifetime = ServiceLifetime.Transient) ServiceLifetime lifetime = ServiceLifetime.Transient)
where THandler : where THandler :
IHandler IHandler
{ {
@@ -62,71 +160,6 @@ public static class IServiceCollectionExtensions
return services; return services;
} }
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services,
IConfiguration configuration)
where TConfiguration :
class, new()
{
return services.AddConfiguration<TConfiguration>(configuration, typeof(TConfiguration).Name, "Settings.json", null);
}
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services,
IConfiguration configuration,
TConfiguration? defaults = null)
where TConfiguration :
class, new()
{
return services.AddConfiguration(configuration, typeof(TConfiguration).Name, "Settings.json", defaults);
}
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection services,
IConfiguration configuration,
string section,
string path = "Settings.json",
TConfiguration? defaults = null,
Action<JsonSerializerOptions>? serializerDelegate = null)
where TConfiguration :
class, new()
{
services.Configure<TConfiguration>(configuration);
services.AddSingleton<IConfigureOptions<TConfiguration>>(new ConfigureNamedOptions<TConfiguration>("", args => { }));
services.AddTransient(provider => provider.GetService<IOptionsMonitor<TConfiguration>>()!.CurrentValue);
services.AddSingleton<IConfigurationWriter<TConfiguration>>(provider =>
{
string? jsonFilePath = null;
if (provider.GetService<IHostEnvironment>() is IHostEnvironment hostEnvironment)
{
IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider;
IFileInfo fileInfo = fileProvider.GetFileInfo(path);
jsonFilePath = fileInfo.PhysicalPath;
}
jsonFilePath ??= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
JsonSerializerOptions? defaultSerializer = null;
if (serializerDelegate is not null)
{
defaultSerializer = new JsonSerializerOptions();
serializerDelegate.Invoke(defaultSerializer);
}
return new ConfigurationWriter<TConfiguration>(jsonFilePath, section, defaultSerializer);
});
if (defaults is not null)
{
}
services.AddTransient(provider => new DefaultConfiguration<TConfiguration>(defaults));
services.AddTransient<IInitializer, ConfigurationInitializer<TConfiguration>>();
services.AddTransient<IWritableConfiguration<TConfiguration>, WritableConfiguration<TConfiguration>>();
return services;
}
public static IServiceCollection AddWidgetTemplate<TWidgetContent>(this IServiceCollection services) public static IServiceCollection AddWidgetTemplate<TWidgetContent>(this IServiceCollection services)
where TWidgetContent : where TWidgetContent :
IWidgetViewModel IWidgetViewModel
@@ -166,23 +199,4 @@ public static class IServiceCollectionExtensions
return services; return services;
} }
public static IServiceCollection AddContentTemplate<TContent, TTemplate>(this IServiceCollection services,
object? key = null)
{
Type contentType = typeof(TContent);
Type templateType = typeof(TTemplate);
key ??= contentType.Name;
services.AddTransient(contentType);
services.TryAddTransient(templateType);
services.AddKeyedTransient(contentType, key);
services.AddKeyedTransient(templateType, key);
services.AddTransient<IContentTemplateDescriptor>(provider => new ContentTemplateDescriptor { ContentType = contentType, TemplateType = templateType, Key = key });
return services;
}
} }