Цель этой библиотеки — значительно упростить создание инструментов консольных приложений, предоставляя вам основы пользовательского контроля и позволяя вам сосредоточиться на ценности вашего бизнеса.
Основное внимание здесь уделяется эффективности и простоте. Это не библиотека для рисования сложной информационной панели в формате ASCII.
[ Menu ( "This is a title" , Description = "This is an optional description" ) ]
public class MainMenu
{
[ Choice ( "This is the display text of the first choice" ) ]
public void Choice1 ( )
{
Console . WriteLine ( "Hello world !" ) ;
}
[ Choice ( "This is the display text of the second choice" ) ]
public void Choice2 ( )
{
Console . WriteLine ( "Goodbye world !" ) ;
}
}
using IHost host = Host . CreateDefaultBuilder ( args )
. ConfigureServices ( ( _ , services ) =>
{
services . AddMenuCLI < MainMenu > ( ) ;
} )
. Build ( ) ;
await host . Services . StartMenu ( ) ;
Вы можете добавить подменю в приложение следующим образом:
[ Menu ( "Submenu title" ) ]
public class SubMenu
{
[ Choice ( "This is the display text of the first choice" ) ]
public void Choice1 ( )
{
Console . WriteLine ( "Hello world !" ) ;
}
}
[ Choice ( "Sub Menu" , typeof ( SubMenu ) ) ]
public void Choice1 ( )
{
Console . WriteLine ( "Doing things..." ) ;
Thread . Sleep ( 1000 ) ;
}
Приложение выполнит содержимое выбора 1, а затем перенаправит в подменю.
Библиотека может обрабатывать асинхронный вызов следующим образом:
[ Choice ( "Async choice" ) ]
public async Task Choice2 ( )
{
Console . WriteLine ( "Doing async things..." ) ;
await Task . Delay ( 3000 ) ;
}
Библиотека может позволить вам настроить подменю на основе результатов обратного вызова:
[ Choice ( "Dynamic Menu" ) ]
public void Choice3 ( [ Menu ( "Dynamic Menu" , Description = "This is a generated menu from a callback" ) ] Menu menu )
{
var random = new Random ( ) ;
var choiceNumber = random . Next ( 9 ) ;
for ( int i = 0 ; i < choiceNumber + 1 ; i ++ )
{
menu . AddMenuChoice ( $ "Choice Id { Guid . NewGuid ( ) } " , ( ) => Console . WriteLine ( "What a choice !" ) ) ;
}
}
Внедрение зависимостей по-прежнему работает, но, возможно, не так, как ожидалось. Выбранный метод обратного вызова выполняется в том же контексте, что и класс регистра. Посмотрите внимательно на пример песочницы для большей точности.
Все классы меню разрешаются путем внедрения зависимостей, поэтому вы тоже можете его использовать! (более подробный пример см. в проекте песочницы)
Чтобы пропустить Console.ReadKey()
и иметь возможность протестировать пользовательскую последовательность, запустите меню с необязательным параметром, как в этом примере:
await host . Services . StartMenu ( true ) ;
Реальный пример E2E-тестов вы можете увидеть в проекте Tests
.
Планируется дополнительная работа, например, более сложное перенаправление подменю в зависимости от возврата обратного вызова, обработка индикатора выполнения и отложенная загрузка классов меню (сейчас они активно загружаются при начальной загрузке приложения).