Added the abilty to load configuration sections using * pattern

This commit is contained in:
TheXamlGuy
2024-04-24 23:08:58 +01:00
parent 672286cbfd
commit 4ffb3257f8
26 changed files with 318 additions and 70 deletions
@@ -0,0 +1,17 @@
using Toolkit.Foundation;
namespace Bitvault;
public partial class CreateVaultNavigationViewModel :
ObservableViewModel,
IMainNavigationViewModel
{
public CreateVaultNavigationViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
}
}
+24
View File
@@ -0,0 +1,24 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Toolkit.Foundation;
namespace Bitvault;
public partial class CreateVaultViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) :
ObservableViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer),
IPrimaryConfirmation
{
[MaybeNull]
[ObservableProperty]
private string name;
public async Task<bool> Confirm()
{
await Publisher.Publish(Create.As(new Vault(Name)));
return true;
}
}
+16
View File
@@ -0,0 +1,16 @@
using Toolkit.Foundation;
namespace Bitvault;
public partial class FooterViewModel :
ObservableCollectionViewModel<IMainNavigationViewModel>
{
public FooterViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
Add<ManageNavigationViewModel>();
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Bitvault
{
public interface IVaultFactory
{
Task CreateAsync(string name, VaultConfiguration configuration);
}
}
+6 -7
View File
@@ -7,11 +7,10 @@ public class LockViewModel(IServiceProvider serviceProvider,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) :
ObservableViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer),
IConfirmation
ObservableViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
public Task<bool> Confirm()
{
return Task.FromResult(false);
}
}
//public Task<bool> Confirm()
//{
// //return Task.FromResult(false);
//}
}
+8 -2
View File
@@ -1,4 +1,5 @@
using Toolkit.Foundation;
using CommunityToolkit.Mvvm.ComponentModel;
using Toolkit.Foundation;
namespace Bitvault;
@@ -6,14 +7,19 @@ namespace Bitvault;
public partial class MainViewModel :
ObservableCollectionViewModel<IMainNavigationViewModel>
{
[ObservableProperty]
private FooterViewModel footer;
public MainViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer,
IContentTemplate template) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
IContentTemplate template,
FooterViewModel footer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
Template = template;
Footer = footer;
}
public IContentTemplate Template { get; set; }
+17
View File
@@ -0,0 +1,17 @@
using Toolkit.Foundation;
namespace Bitvault;
public partial class ManageNavigationViewModel :
ObservableViewModel,
IMainNavigationViewModel
{
public ManageNavigationViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
}
}
+23
View File
@@ -0,0 +1,23 @@
using Avalonia.Styling;
using Toolkit.Foundation;
namespace Bitvault;
public partial class ManageViewModel :
ObservableCollectionViewModel,
IMainNavigationViewModel
{
public ManageViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer,
IContentTemplate template) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
Template = template;
Add<CreateVaultNavigationViewModel>();
}
public IContentTemplate Template { get; set; }
}
+3
View File
@@ -0,0 +1,3 @@
namespace Bitvault;
public record Vault(string Name);
-55
View File
@@ -1,55 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Toolkit.Foundation;
namespace Bitvault;
public class VaultComponentsInitializer(IServiceProvider provider,
IProxyServiceCollection<IComponentBuilder> proxy,
IEnumerable<IConfigurationDescriptor<VaultConfiguration>> configurations,
IComponentScopeCollection scopes,
IVaultHostCollection vaults) : IInitializer
{
public async Task Initialize()
{
foreach (IConfigurationDescriptor<VaultConfiguration> configuration in configurations)
{
if (provider.GetRequiredService<IVaultComponent>() is IVaultComponent component)
{
IComponentBuilder builder = component.Create();
builder.AddServices(services =>
{
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IPublisher>>());
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextCollection>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextProvider>());
services.AddScoped(_ =>
provider.GetRequiredService<IComponentScopeCollection>());
services.AddTransient(_ =>
provider.GetRequiredService<IComponentScopeProvider>());
services.AddRange(proxy.Services);
services.AddSingleton(new ComponentScope(configuration.Section));
});
builder.AddConfiguration(configuration.Section, configuration.Value);
IComponentHost host = builder.Build();
scopes.Add(new ComponentScopeDescriptor(configuration.Section,
host.Services.GetRequiredService<IServiceProvider>()));
vaults.Add(host);
await host.StartAsync();
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
using Toolkit.Foundation;
namespace Bitvault;
public class VaultConfigurationInitializer(IEnumerable<IConfigurationDescriptor<VaultConfiguration>> configurations,
IVaultFactory factory) : IInitializer
{
public async Task Initialize()
{
foreach (IConfigurationDescriptor<VaultConfiguration> configuration in configurations)
{
await factory.CreateAsync(configuration.Section,
configuration.Value);
}
}
}
+51
View File
@@ -0,0 +1,51 @@
using Microsoft.Extensions.DependencyInjection;
using Toolkit.Foundation;
namespace Bitvault;
public class VaultFactory(IServiceProvider provider,
IProxyServiceCollection<IComponentBuilder> proxy,
IComponentScopeCollection scopes,
IVaultHostCollection vaults) : IVaultFactory
{
public async Task CreateAsync(string name,
VaultConfiguration configuration)
{
if (provider.GetRequiredService<IVaultComponent>() is IVaultComponent component)
{
IComponentBuilder builder = component.Create();
builder.AddServices(services =>
{
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IPublisher>>());
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextCollection>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextProvider>());
services.AddScoped(_ =>
provider.GetRequiredService<IComponentScopeCollection>());
services.AddTransient(_ =>
provider.GetRequiredService<IComponentScopeProvider>());
services.AddRange(proxy.Services);
services.AddSingleton(new ComponentScope(name));
});
builder.AddConfiguration(name, configuration);
IComponentHost host = builder.Build();
scopes.Add(new ComponentScopeDescriptor(name,
host.Services.GetRequiredService<IServiceProvider>()));
vaults.Add(host);
await host.StartAsync();
}
}
}
+15
View File
@@ -0,0 +1,15 @@
using Toolkit.Foundation;
namespace Bitvault;
public class VaultHandler(IVaultFactory factory) : INotificationHandler<Create<Vault>>
{
public async Task Handle(Create<Vault> args,
CancellationToken cancellationToken = default)
{
if (args.Value is Vault vault)
{
await factory.CreateAsync($"Vault:{vault.Name}", new VaultConfiguration { Name = vault.Name });
}
}
}