Refactor command handlers and Startup
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
using FileTime.App.Core.Command;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Services
|
||||||
|
{
|
||||||
|
public interface ICommandHandler
|
||||||
|
{
|
||||||
|
bool CanHandleCommand(Commands command);
|
||||||
|
Task HandleCommandAsync(Commands command);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using FileTime.App.Core.Command;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Services.CommandHandler
|
||||||
|
{
|
||||||
|
public abstract class CommandHanderBase : ICommandHandler
|
||||||
|
{
|
||||||
|
private readonly Dictionary<Commands, Func<Task>> _commandHandlers = new();
|
||||||
|
public bool CanHandleCommand(Commands command) => _commandHandlers.ContainsKey(command);
|
||||||
|
|
||||||
|
public async Task HandleCommandAsync(Commands command) => await _commandHandlers[command].Invoke();
|
||||||
|
|
||||||
|
protected void AddCommandHandler(Commands command, Func<Task> handler) => _commandHandlers.Add(command, handler);
|
||||||
|
protected void AddCommandHandlers(IEnumerable<(Commands command, Func<Task> handler)> commandHandlers)
|
||||||
|
{
|
||||||
|
foreach (var (command, handler) in commandHandlers)
|
||||||
|
{
|
||||||
|
AddCommandHandler(command, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RemoveCommandHandler(Commands command) => _commandHandlers.Remove(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Reactive.Linq;
|
||||||
|
using FileTime.App.Core.Command;
|
||||||
|
using FileTime.App.Core.Extensions;
|
||||||
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Services.CommandHandler
|
||||||
|
{
|
||||||
|
public class NavigationCommandHandler : CommandHanderBase
|
||||||
|
{
|
||||||
|
private readonly IAppState _appState;
|
||||||
|
private ITabViewModel? _selectedTab;
|
||||||
|
private IContainer? _currentLocation;
|
||||||
|
private IItemViewModel? _currentSelectedItem;
|
||||||
|
private List<IItemViewModel> _currentItems = new();
|
||||||
|
|
||||||
|
public NavigationCommandHandler(IAppState appState)
|
||||||
|
{
|
||||||
|
_appState = appState;
|
||||||
|
|
||||||
|
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||||
|
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation).Switch().Subscribe(l => _currentLocation = l);
|
||||||
|
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IItemViewModel?>(null) : t.CurrentSelectedItem).Switch().Subscribe(l => _currentSelectedItem = l);
|
||||||
|
_appState.SelectedTab.Select(t => t == null ? Observable.Return(Enumerable.Empty<IItemViewModel>()) : t.CurrentItems).Switch().Subscribe(i => _currentItems = i.ToList());
|
||||||
|
|
||||||
|
AddCommandHandlers(new (Commands, Func<Task>)[]
|
||||||
|
{
|
||||||
|
(Commands.GoUp, GoUp),
|
||||||
|
(Commands.MoveCursorDown, MoveCursorDown),
|
||||||
|
(Commands.MoveCursorUp, MoveCursorUp),
|
||||||
|
(Commands.Open, OpenContainer),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task OpenContainer()
|
||||||
|
{
|
||||||
|
if (_currentSelectedItem is not IContainerViewModel containerViewModel || containerViewModel.Container is null) return Task.CompletedTask;
|
||||||
|
|
||||||
|
_selectedTab?.Tab?.SetCurrentLocation(containerViewModel.Container);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GoUp()
|
||||||
|
{
|
||||||
|
if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return;
|
||||||
|
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task MoveCursorDown()
|
||||||
|
{
|
||||||
|
SelectNewSelectedItem(i => i.SkipWhile(i => i != _currentSelectedItem).Skip(1).FirstOrDefault());
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task MoveCursorUp()
|
||||||
|
{
|
||||||
|
SelectNewSelectedItem(i => i.TakeWhile(i => i != _currentSelectedItem).LastOrDefault());
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectNewSelectedItem(Func<IEnumerable<IItemViewModel>, IItemViewModel?> getNewSelected)
|
||||||
|
{
|
||||||
|
if (_selectedTab is null || _currentLocation is null) return;
|
||||||
|
|
||||||
|
var newSelectedItem = getNewSelected(_currentItems);
|
||||||
|
if (newSelectedItem == null) return;
|
||||||
|
|
||||||
|
_selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,129 +1,79 @@
|
|||||||
using System.Reactive.Linq;
|
|
||||||
using FileTime.App.Core.Command;
|
using FileTime.App.Core.Command;
|
||||||
using FileTime.App.Core.Extensions;
|
|
||||||
using FileTime.App.Core.ViewModels;
|
|
||||||
using FileTime.Core.Models;
|
|
||||||
|
|
||||||
namespace FileTime.App.Core.Services
|
namespace FileTime.App.Core.Services
|
||||||
{
|
{
|
||||||
public class CommandHandlerService : ICommandHandlerService
|
public class CommandHandlerService : ICommandHandlerService
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Commands, Func<Task>> _commandHandlers;
|
private readonly IEnumerable<ICommandHandler> _commandHandlers;
|
||||||
private readonly IAppState _appState;
|
|
||||||
private ITabViewModel? _selectedTab;
|
|
||||||
private IContainer? _currentLocation;
|
|
||||||
private IItemViewModel? _currentSelectedItem;
|
|
||||||
private List<IItemViewModel> _currentItems = new();
|
|
||||||
|
|
||||||
public CommandHandlerService(IAppState appState)
|
public CommandHandlerService(IEnumerable<ICommandHandler> commandHandlers)
|
||||||
{
|
{
|
||||||
_appState = appState;
|
_commandHandlers = commandHandlers;
|
||||||
|
|
||||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
//(Commands.AutoRefresh, ToggleAutoRefresh),
|
||||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation).Switch().Subscribe(l => _currentLocation = l);
|
//(Commands.ChangeTimelineMode, ChangeTimelineMode),
|
||||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IItemViewModel?>(null) : t.CurrentSelectedItem).Switch().Subscribe(l => _currentSelectedItem = l);
|
//(Commands.CloseTab, CloseTab),
|
||||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return(Enumerable.Empty<IItemViewModel>()) : t.CurrentItems).Switch().Subscribe(i => _currentItems = i.ToList());
|
//(Commands.Compress, Compress),
|
||||||
|
//(Commands.Copy, Copy),
|
||||||
_commandHandlers = new Dictionary<Commands, Func<Task>>
|
//(Commands.CopyHash, CopyHash),
|
||||||
{
|
//(Commands.CopyPath, CopyPath),
|
||||||
//{Commands.AutoRefresh, ToggleAutoRefresh},
|
//(Commands.CreateContainer, CreateContainer),
|
||||||
//{Commands.ChangeTimelineMode, ChangeTimelineMode},
|
//(Commands.CreateElement, CreateElement),
|
||||||
//{Commands.CloseTab, CloseTab},
|
//(Commands.Cut, Cut),
|
||||||
//{Commands.Compress, Compress},
|
//(Commands.Edit, Edit),
|
||||||
//{Commands.Copy, Copy},
|
//(Commands.EnterRapidTravel, EnterRapidTravelMode),
|
||||||
//{Commands.CopyHash, CopyHash},
|
//(Commands.FindByName, FindByName),
|
||||||
//{Commands.CopyPath, CopyPath},
|
//(Commands.FindByNameRegex, FindByNameRegex),
|
||||||
//{Commands.CreateContainer, CreateContainer},
|
//(Commands.GoToHome, GotToHome),
|
||||||
//{Commands.CreateElement, CreateElement},
|
//(Commands.GoToPath, GoToContainer),
|
||||||
//{Commands.Cut, Cut},
|
//(Commands.GoToProvider, GotToProvider),
|
||||||
//{Commands.Edit, Edit},
|
//(Commands.GoToRoot, GotToRoot),
|
||||||
//{Commands.EnterRapidTravel, EnterRapidTravelMode},
|
//(Commands.HardDelete, HardDelete),
|
||||||
//{Commands.FindByName, FindByName},
|
//(Commands.Mark, MarkCurrentItem),
|
||||||
//{Commands.FindByNameRegex, FindByNameRegex},
|
//(Commands.MoveCursorDownPage, MoveCursorDownPage),
|
||||||
//{Commands.GoToHome, GotToHome},
|
//(Commands.MoveCursorUpPage, MoveCursorUpPage),
|
||||||
//{Commands.GoToPath, GoToContainer},
|
//(Commands.MoveToFirst, MoveToFirst),
|
||||||
//{Commands.GoToProvider, GotToProvider},
|
//(Commands.MoveToLast, MoveToLast),
|
||||||
//{Commands.GoToRoot, GotToRoot},
|
//(Commands.NextTimelineBlock, SelectNextTimelineBlock),
|
||||||
{Commands.GoUp, GoUp},
|
//(Commands.NextTimelineCommand, SelectNextTimelineCommand),
|
||||||
//{Commands.HardDelete, HardDelete},
|
//(Commands.OpenInFileBrowser, OpenInDefaultFileExplorer),
|
||||||
//{Commands.Mark, MarkCurrentItem},
|
//(Commands.OpenOrRun, OpenOrRun),
|
||||||
{Commands.MoveCursorDown, MoveCursorDown},
|
//(Commands.PasteMerge, PasteMerge),
|
||||||
//{Commands.MoveCursorDownPage, MoveCursorDownPage},
|
//(Commands.PasteOverwrite, PasteOverwrite),
|
||||||
{Commands.MoveCursorUp, MoveCursorUp},
|
//(Commands.PasteSkip, PasteSkip),
|
||||||
//{Commands.MoveCursorUpPage, MoveCursorUpPage},
|
//(Commands.PinFavorite, PinFavorite),
|
||||||
//{Commands.MoveToFirst, MoveToFirst},
|
//(Commands.PreviousTimelineBlock, SelectPreviousTimelineBlock),
|
||||||
//{Commands.MoveToLast, MoveToLast},
|
//(Commands.PreviousTimelineCommand, SelectPreviousTimelineCommand),
|
||||||
//{Commands.NextTimelineBlock, SelectNextTimelineBlock},
|
//(Commands.Refresh, RefreshCurrentLocation),
|
||||||
//{Commands.NextTimelineCommand, SelectNextTimelineCommand},
|
//(Commands.Rename, Rename),
|
||||||
{Commands.Open, OpenContainer},
|
//(Commands.RunCommand, RunCommandInContainer),
|
||||||
//{Commands.OpenInFileBrowser, OpenInDefaultFileExplorer},
|
//(Commands.ScanContainerSize, ScanContainerSize),
|
||||||
//{Commands.OpenOrRun, OpenOrRun},
|
//(Commands.ShowAllShotcut, ShowAllShortcut),
|
||||||
//{Commands.PasteMerge, PasteMerge},
|
//(Commands.SoftDelete, SoftDelete),
|
||||||
//{Commands.PasteOverwrite, PasteOverwrite},
|
//(Commands.SwitchToLastTab, async() => await SwitchToTab(-1)),
|
||||||
//{Commands.PasteSkip, PasteSkip},
|
//(Commands.SwitchToTab1, async() => await SwitchToTab(1)),
|
||||||
//{Commands.PinFavorite, PinFavorite},
|
//(Commands.SwitchToTab2, async() => await SwitchToTab(2)),
|
||||||
//{Commands.PreviousTimelineBlock, SelectPreviousTimelineBlock},
|
//(Commands.SwitchToTab3, async() => await SwitchToTab(3)),
|
||||||
//{Commands.PreviousTimelineCommand, SelectPreviousTimelineCommand},
|
//(Commands.SwitchToTab4, async() => await SwitchToTab(4)),
|
||||||
//{Commands.Refresh, RefreshCurrentLocation},
|
//(Commands.SwitchToTab5, async() => await SwitchToTab(5)),
|
||||||
//{Commands.Rename, Rename},
|
//(Commands.SwitchToTab6, async() => await SwitchToTab(6)),
|
||||||
//{Commands.RunCommand, RunCommandInContainer},
|
//(Commands.SwitchToTab7, async() => await SwitchToTab(7)),
|
||||||
//{Commands.ScanContainerSize, ScanContainerSize},
|
//(Commands.SwitchToTab8, async() => await SwitchToTab(8)),
|
||||||
//{Commands.ShowAllShotcut, ShowAllShortcut},
|
//(Commands.TimelinePause, PauseTimeline),
|
||||||
//{Commands.SoftDelete, SoftDelete},
|
//(Commands.TimelineRefresh, RefreshTimeline),
|
||||||
//{Commands.SwitchToLastTab, async() => await SwitchToTab(-1)},
|
//(Commands.TimelineStart, ContinueTimeline),
|
||||||
//{Commands.SwitchToTab1, async() => await SwitchToTab(1)},
|
//(Commands.ToggleAdvancedIcons, ToggleAdvancedIcons),
|
||||||
//{Commands.SwitchToTab2, async() => await SwitchToTab(2)},
|
//(Commands.ToggleHidden, ToggleHidden),
|
||||||
//{Commands.SwitchToTab3, async() => await SwitchToTab(3)},
|
|
||||||
//{Commands.SwitchToTab4, async() => await SwitchToTab(4)},
|
|
||||||
//{Commands.SwitchToTab5, async() => await SwitchToTab(5)},
|
|
||||||
//{Commands.SwitchToTab6, async() => await SwitchToTab(6)},
|
|
||||||
//{Commands.SwitchToTab7, async() => await SwitchToTab(7)},
|
|
||||||
//{Commands.SwitchToTab8, async() => await SwitchToTab(8)},
|
|
||||||
//{Commands.TimelinePause, PauseTimeline},
|
|
||||||
//{Commands.TimelineRefresh, RefreshTimeline},
|
|
||||||
//{Commands.TimelineStart, ContinueTimeline},
|
|
||||||
//{Commands.ToggleAdvancedIcons, ToggleAdvancedIcons},
|
|
||||||
//{Commands.ToggleHidden, ToggleHidden},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HandleCommandAsync(Commands command) =>
|
public async Task HandleCommandAsync(Commands command)
|
||||||
await _commandHandlers[command].Invoke();
|
|
||||||
|
|
||||||
private Task OpenContainer()
|
|
||||||
{
|
{
|
||||||
if (_currentSelectedItem is not IContainerViewModel containerViewModel || containerViewModel.Container is null) return Task.CompletedTask;
|
var handler = _commandHandlers.FirstOrDefault(h => h.CanHandleCommand(command));
|
||||||
|
|
||||||
_selectedTab?.Tab?.SetCurrentLocation(containerViewModel.Container);
|
if (handler != null)
|
||||||
return Task.CompletedTask;
|
{
|
||||||
|
await handler.HandleCommandAsync(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GoUp()
|
|
||||||
{
|
|
||||||
if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return;
|
|
||||||
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task MoveCursorDown()
|
|
||||||
{
|
|
||||||
SelectNewSelectedItem(i => i.SkipWhile(i => i != _currentSelectedItem).Skip(1).FirstOrDefault());
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task MoveCursorUp()
|
|
||||||
{
|
|
||||||
SelectNewSelectedItem(i => i.TakeWhile(i => i != _currentSelectedItem).LastOrDefault());
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectNewSelectedItem(Func<IEnumerable<IItemViewModel>, IItemViewModel?> getNewSelected)
|
|
||||||
{
|
|
||||||
if (_selectedTab is null || _currentLocation is null) return;
|
|
||||||
|
|
||||||
var newSelectedItem = getNewSelected(_currentItems);
|
|
||||||
if (newSelectedItem == null) return;
|
|
||||||
|
|
||||||
_selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
27
src/AppCommon/FileTime.App.Core/Startup.cs
Normal file
27
src/AppCommon/FileTime.App.Core/Startup.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using FileTime.App.Core.Services;
|
||||||
|
using FileTime.App.Core.Services.CommandHandler;
|
||||||
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core
|
||||||
|
{
|
||||||
|
public static class Startup
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection)
|
||||||
|
{
|
||||||
|
return serviceCollection
|
||||||
|
.AddTransient<ITabViewModel, TabViewModel>()
|
||||||
|
.AddTransient<IContainerViewModel, ContainerViewModel>()
|
||||||
|
.AddTransient<IElementViewModel, ElementViewModel>()
|
||||||
|
.AddTransient<IItemNameConverterService, ItemNameConverterService>()
|
||||||
|
.AddSingleton<ICommandHandlerService, CommandHandlerService>()
|
||||||
|
.AddCommandHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IServiceCollection AddCommandHandlers(this IServiceCollection serviceCollection)
|
||||||
|
{
|
||||||
|
return serviceCollection
|
||||||
|
.AddSingleton<ICommandHandler, NavigationCommandHandler>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using FileTime.App.Core;
|
||||||
|
using FileTime.Core.Services;
|
||||||
using FileTime.Providers.Local;
|
using FileTime.Providers.Local;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@@ -10,6 +12,8 @@ namespace FileTime.App.DependencyInjection
|
|||||||
serviceCollection ??= new ServiceCollection();
|
serviceCollection ??= new ServiceCollection();
|
||||||
|
|
||||||
return serviceCollection
|
return serviceCollection
|
||||||
|
.AddTransient<ITab, Tab>()
|
||||||
|
.AddCoreAppServices()
|
||||||
.AddLocalServices();
|
.AddLocalServices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Providers\FileTime.Providers.Local\FileTime.Providers.Local.csproj" />
|
<ProjectReference Include="..\..\Providers\FileTime.Providers.Local\FileTime.Providers.Local.csproj" />
|
||||||
|
<ProjectReference Include="..\FileTime.App.Core\FileTime.App.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace FileTime.GuiApp
|
|||||||
.RegisterDefaultServices()
|
.RegisterDefaultServices()
|
||||||
.AddConfiguration()
|
.AddConfiguration()
|
||||||
.RegisterLogging()
|
.RegisterLogging()
|
||||||
|
.RegisterServices()
|
||||||
.AddViewModels()
|
.AddViewModels()
|
||||||
.BuildServiceProvider()
|
.BuildServiceProvider()
|
||||||
.InitSerilog();
|
.InitSerilog();
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using FileTime.App.Core;
|
|
||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.Core.Services;
|
|
||||||
using FileTime.GuiApp.Configuration;
|
using FileTime.GuiApp.Configuration;
|
||||||
using FileTime.GuiApp.Logging;
|
using FileTime.GuiApp.Logging;
|
||||||
using FileTime.GuiApp.Services;
|
using FileTime.GuiApp.Services;
|
||||||
@@ -23,17 +21,12 @@ namespace FileTime.GuiApp
|
|||||||
.AddSingleton<MainWindowViewModel>()
|
.AddSingleton<MainWindowViewModel>()
|
||||||
.AddSingleton<GuiAppState>()
|
.AddSingleton<GuiAppState>()
|
||||||
.AddSingleton<IAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>())
|
.AddSingleton<IAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>())
|
||||||
.AddSingleton<IGuiAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>())
|
.AddSingleton<IGuiAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>());
|
||||||
.AddSingleton<DefaultModeKeyInputHandler>()
|
}
|
||||||
.AddSingleton<RapidTravelModeKeyInputHandler>()
|
internal static IServiceCollection RegisterServices(this IServiceCollection serviceCollection)
|
||||||
|
{
|
||||||
|
return serviceCollection
|
||||||
.AddSingleton<IRxSchedulerService, AvaloniaRxSchedulerService>()
|
.AddSingleton<IRxSchedulerService, AvaloniaRxSchedulerService>()
|
||||||
//TODO: move??
|
|
||||||
.AddTransient<ITab, Tab>()
|
|
||||||
.AddTransient<ITabViewModel, TabViewModel>()
|
|
||||||
.AddTransient<IContainerViewModel, ContainerViewModel>()
|
|
||||||
.AddTransient<IElementViewModel, ElementViewModel>()
|
|
||||||
.AddTransient<IItemNameConverterService, ItemNameConverterService>()
|
|
||||||
.AddSingleton<ICommandHandlerService, CommandHandlerService>()
|
|
||||||
.AddSingleton<IKeyInputHandlerService, KeyInputHandlerService>()
|
.AddSingleton<IKeyInputHandlerService, KeyInputHandlerService>()
|
||||||
.AddSingleton<IDefaultModeKeyInputHandler, DefaultModeKeyInputHandler>()
|
.AddSingleton<IDefaultModeKeyInputHandler, DefaultModeKeyInputHandler>()
|
||||||
.AddSingleton<IKeyboardConfigurationService, KeyboardConfigurationService>()
|
.AddSingleton<IKeyboardConfigurationService, KeyboardConfigurationService>()
|
||||||
|
|||||||
Reference in New Issue
Block a user