Enabled ability to order containers and the ability to insert new containers to their correct order

This commit is contained in:
TheXamlGuy
2024-05-12 18:28:13 +01:00
parent 40671e38b6
commit 77e79a603e
11 changed files with 77 additions and 69 deletions
+2 -2
View File
@@ -49,7 +49,7 @@ public partial class App : Application
services.AddTransient<IKeyDeriver, KeyDeriver>(); services.AddTransient<IKeyDeriver, KeyDeriver>();
services.AddTransient<ISecurityKeyFactory, SecurityKeyFactory>(); services.AddTransient<ISecurityKeyFactory, SecurityKeyFactory>();
services.AddTransient<IContainerFactory, ContainerFactory>(); services.AddTransient<IContainerStorageFactory, ContainerStorageFactory>();
services.TryAddSingleton<IValueStore<SecurityKey>, ValueStore<SecurityKey>>(); services.TryAddSingleton<IValueStore<SecurityKey>, ValueStore<SecurityKey>>();
services.TryAddSingleton<IValueStore<ContainerConnection>, ValueStore<ContainerConnection>>(); services.TryAddSingleton<IValueStore<ContainerConnection>, ValueStore<ContainerConnection>>();
@@ -93,7 +93,7 @@ public partial class App : Application
}); });
})!); })!);
services.AddTransient<IContainerComponentFactory, ContainerComponentFactory>(); services.AddTransient<IContainerFactory, ContainerFactory>();
services.AddHandler<CreateContainerHandler>(); services.AddHandler<CreateContainerHandler>();
services.AddSingleton<IContainerHostCollection, ContainerHostCollection>(); services.AddSingleton<IContainerHostCollection, ContainerHostCollection>();
+10 -3
View File
@@ -1,22 +1,29 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Toolkit.Foundation; using Toolkit.Foundation;
namespace Bitvault; namespace Bitvault;
public record ContainerActivatedHandler(IPublisher publisher) : public class ContainerActivatedHandler(IContainerHostCollection containers,
IPublisher publisher) :
INotificationHandler<Activated<IComponentHost>> INotificationHandler<Activated<IComponentHost>>
{ {
public async Task Handle(Activated<IComponentHost> args, CancellationToken cancellationToken = default) public async Task Handle(Activated<IComponentHost> args, CancellationToken cancellationToken = default)
{ {
if (args.Value is IComponentHost container) if (args.Value is IComponentHost container)
{ {
List<IComponentHost> sortedContainers = [.. containers, container];
sortedContainers = [.. sortedContainers.OrderBy(x => x.GetConfiguration< ContainerConfiguration>() is ContainerConfiguration configuration ? configuration.Name : null)];
int index = sortedContainers.IndexOf(container);
if (container.Services.GetRequiredService<ContainerConfiguration>() is ContainerConfiguration configuration) if (container.Services.GetRequiredService<ContainerConfiguration>() is ContainerConfiguration configuration)
{ {
if (container.Services.GetRequiredService<IServiceFactory>() is IServiceFactory factory) if (container.Services.GetRequiredService<IServiceFactory>() is IServiceFactory factory)
{ {
if (factory.Create<ContainerNavigationViewModel>(configuration.Name) is ContainerNavigationViewModel viewModel) if (factory.Create<ContainerNavigationViewModel>(configuration.Name) is ContainerNavigationViewModel viewModel)
{ {
await publisher.Publish(new Create<IMainNavigationViewModel>(viewModel), await publisher.Publish(new Insert<IMainNavigationViewModel>(index, viewModel),
nameof(MainViewModel), cancellationToken); nameof(MainViewModel), cancellationToken);
} }
} }
-18
View File
@@ -1,18 +0,0 @@
using Toolkit.Foundation;
namespace Bitvault;
public class ContainerComponentFactory(IComponentFactory componentFactory) :
IContainerComponentFactory
{
public IComponentHost? Create(string name)
{
if (componentFactory.Create<IContainerComponent, ContainerConfiguration>($"Vault:{name}",
new ContainerConfiguration { Name = name }) is IComponentHost host)
{
return host;
}
return default;
}
}
+7 -30
View File
@@ -1,41 +1,18 @@
using Bitvault.Data; using Toolkit.Foundation;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Toolkit.Foundation;
namespace Bitvault; namespace Bitvault;
public class ContainerFactory(IValueStore<ContainerConnection> connection, public class ContainerFactory(IComponentFactory componentFactory) :
IHostEnvironment environment,
IServiceProvider provider) :
IContainerFactory IContainerFactory
{ {
public async Task<bool> Create(string name, public IComponentHost? Create(string name)
SecurityKey key)
{ {
connection.Set(new ContainerConnection($"Data Source={Path.Combine(environment.ContentRootPath, name)}" + if (componentFactory.Create<IContainerComponent, ContainerConfiguration>($"Vault:{name}",
$".vault;Mode=ReadWriteCreate;Pooling=false;Password={Convert.ToBase64String(key.DecryptedKey)}")); new ContainerConfiguration { Name = name }) is IComponentHost host)
IDbContextFactory<ContainerDbContext> dbContextFactory = provider.GetRequiredService<IDbContextFactory<ContainerDbContext>>();
using ContainerDbContext context = await dbContextFactory.CreateDbContextAsync();
try
{ {
await Task.Run(async () => return host;
{
await context.Database.EnsureCreatedAsync().ConfigureAwait(false);
await context.Database.CloseConnectionAsync().ConfigureAwait(false);
context.Database.SetConnectionString(null);
}).ConfigureAwait(false);
}
catch
{
return false;
} }
return true; return default;
} }
} }
+41
View File
@@ -0,0 +1,41 @@
using Bitvault.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Toolkit.Foundation;
namespace Bitvault;
public class ContainerStorageFactory(IValueStore<ContainerConnection> connection,
IHostEnvironment environment,
IServiceProvider provider) :
IContainerStorageFactory
{
public async Task<bool> Create(string name,
SecurityKey key)
{
connection.Set(new ContainerConnection($"Data Source={Path.Combine(environment.ContentRootPath, name)}" +
$".vault;Mode=ReadWriteCreate;Pooling=false;Password={Convert.ToBase64String(key.DecryptedKey)}"));
IDbContextFactory<ContainerDbContext> dbContextFactory = provider.GetRequiredService<IDbContextFactory<ContainerDbContext>>();
using ContainerDbContext context = await dbContextFactory.CreateDbContextAsync();
try
{
await Task.Run(async () =>
{
await context.Database.EnsureCreatedAsync().ConfigureAwait(false);
await context.Database.CloseConnectionAsync().ConfigureAwait(false);
context.Database.SetConnectionString(null);
}).ConfigureAwait(false);
}
catch
{
return false;
}
return true;
}
}
+2 -2
View File
@@ -5,7 +5,7 @@ using Toolkit.Foundation;
namespace Bitvault; namespace Bitvault;
public class CreateContainerHandler(IContainerComponentFactory componentFactory, public class CreateContainerHandler(IContainerFactory componentFactory,
IPublisher publisher) : IPublisher publisher) :
IHandler<Create<Container>, bool> IHandler<Create<Container>, bool>
{ {
@@ -19,7 +19,7 @@ public class CreateContainerHandler(IContainerComponentFactory componentFactory,
{ {
ISecurityKeyFactory keyVaultFactory = host.Services.GetRequiredService<ISecurityKeyFactory>(); ISecurityKeyFactory keyVaultFactory = host.Services.GetRequiredService<ISecurityKeyFactory>();
IValueStore<SecurityKey> secureKeyStore = host.Services.GetRequiredService<IValueStore<SecurityKey>>(); IValueStore<SecurityKey> secureKeyStore = host.Services.GetRequiredService<IValueStore<SecurityKey>>();
IContainerFactory containerFactory = host.Services.GetRequiredService<IContainerFactory>(); IContainerStorageFactory containerFactory = host.Services.GetRequiredService<IContainerStorageFactory>();
if (keyVaultFactory.Create(Encoding.UTF8.GetBytes(password)) is SecurityKey key) if (keyVaultFactory.Create(Encoding.UTF8.GetBytes(password)) is SecurityKey key)
{ {
-9
View File
@@ -1,9 +0,0 @@
using Toolkit.Foundation;
namespace Bitvault
{
public interface IContainerComponentFactory
{
IComponentHost? Create(string name);
}
}
+6 -3
View File
@@ -1,6 +1,9 @@
namespace Bitvault; using Toolkit.Foundation;
public interface IContainerFactory namespace Bitvault
{ {
Task<bool> Create(string name, SecurityKey key); public interface IContainerFactory
{
IComponentHost? Create(string name);
}
} }
+6
View File
@@ -0,0 +1,6 @@
namespace Bitvault;
public interface IContainerStorageFactory
{
Task<bool> Create(string name, SecurityKey key);
}
+2 -1
View File
@@ -10,7 +10,8 @@ public class MainViewModelHandler(IPublisher publisher,
public async Task Handle(Enumerate<IMainNavigationViewModel> args, public async Task Handle(Enumerate<IMainNavigationViewModel> args,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
foreach (IComponentHost container in containers) foreach (IComponentHost container in containers.OrderBy(x => x.GetConfiguration<ContainerConfiguration>()
is ContainerConfiguration configuration ? configuration.Name : null))
{ {
if (container.Services.GetRequiredService<ContainerConfiguration>() is ContainerConfiguration configuration) if (container.Services.GetRequiredService<ContainerConfiguration>() is ContainerConfiguration configuration)
{ {
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Bitvault;
public class OpenContainerHandler(ContainerConfiguration configuration, public class OpenContainerHandler(ContainerConfiguration configuration,
ISecurityKeyFactory keyVaultFactory, ISecurityKeyFactory keyVaultFactory,
IContainerFactory vaultStorage) : IContainerStorageFactory vaultStorage) :
IHandler<Open<Container>, bool> IHandler<Open<Container>, bool>
{ {
public async Task<bool> Handle(Open<Container> args, public async Task<bool> Handle(Open<Container> args,