O objetivo desta biblioteca é simplificar bastante a criação de ferramentas de aplicativos de console, gerenciando para você os princípios básicos do controle do usuário e permitindo que você se concentre no valor do seu negócio.
O foco aqui é eficiência e simplicidade. Esta não é uma biblioteca para desenhar um painel complexo em arte 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 ( ) ;
Você pode adicionar submenus ao aplicativo assim:
[ 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 ) ;
}
O aplicativo executará o conteúdo de Choice1 e redirecionará para o SubMenu.
A biblioteca pode lidar com chamadas assíncronas assim:
[ Choice ( "Async choice" ) ]
public async Task Choice2 ( )
{
Console . WriteLine ( "Doing async things..." ) ;
await Task . Delay ( 3000 ) ;
}
A biblioteca permite configurar um submenu com base nos resultados do retorno de chamada:
[ 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 !" ) ) ;
}
}
A injeção de dependência ainda funciona, mas talvez não como esperado. O método de retorno de chamada escolhido é executado no mesmo contexto da classe de registro. Observe atentamente o exemplo do sandbox para obter mais precisões.
Todas as classes do menu são resolvidas por injeção de dependência, então você também pode usá-lo! (veja o projeto sandbox para um exemplo mais detalhado)
Para pular o Console.ReadKey()
e poder testar uma sequência de usuário, inicie o menu com o parâmetro opcional como neste exemplo:
await host . Services . StartMenu ( true ) ;
Você pode ver um exemplo real de testes E2E no projeto Tests
.
Mais trabalho está planejado, como um redirecionamento de submenu mais complexo, dependendo do retorno de chamada, manipulação da barra de progresso e carregamento lento das classes de menu (no momento, elas são carregadas avidamente na inicialização do aplicativo).