This blog is part of a series of blog posts looking at .Net packages to help .Net Developers create console apps.
- Part 1 - Crayon
- Part 2 - Cocona
Cocona
Cocona is a "Micro Framework" for building .Net Core console Applications, Written by Mayuki Sawatari
Its available on Github - https://github.com/mayuki/Cocona
and on Nuget https://www.nuget.org/packages/Cocona/
Getting started
You can create a very simple console app with just the following line
CoconaApp.Run((string name, int age) => { Console.WriteLine($"Hello {name} you are {age}.") });
Inspiration
The inspiration for Cocona comes from the work done on .Net Minimal Apis
so a console application can be structured as
using Cocona;
var app = CoconaApp.Create(); // is a shorthand for `CoconaApp.CreateBuilder().Build()`
app.AddCommand("function1", () => { Console.WriteLine("Do function1 Code here"); });
app.AddCommand("function2", () => { Console.WriteLine("Do function2 Code here"); });
app.AddCommand("function3", () => { Console.WriteLine("Do function3 Code here"); });
app.AddCommand("function4", () => { Console.WriteLine("Do function4 Code here"); });
app.Run();
which is very similar to the Minimal Web Api Builder.
Uses Familiar Features
Cocona uses the standard .Net Core "Extensions.*" Libraries for Dependency Injection and Logging
using Cocona;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var builder = CoconaApp.CreateBuilder();
builder.Services.AddSingleton<IMyService, MyService>();
var app = builder.Build();
app.AddCommand("function1", ( [Argument] string stringInput ,IMyService myService )
=> { myService.DoFunction1(stringInput); });
app.AddCommand("function2", ( [Argument] int numberInput ,IMyService myService)
=> { myService.DoFunction2(numberInput); });
app.AddCommand("function3", ( [Argument] DateTime dateInput ,IMyService myService)
=> { myService.DoFunction3(dateInput); });
app.AddCommand("function4", ( [Argument] bool boolInput ,IMyService myService)
=> { myService.DoFunction4(boolInput); });
app.Run();
public interface IMyService
{
void DoFunction1(string input);
void DoFunction2(int input);
void DoFunction3(DateTime input);
void DoFunction4(bool input);
}
public class MyService : IMyService
{
private readonly ILogger _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
public void DoFunction1(string input)
{
_logger.LogInformation(input);
}
public void DoFunction2(int input)
{
_logger.LogInformation(input.ToString());
}
public void DoFunction3(DateTime input)
{
_logger.LogInformation(input.ToLongDateString());
}
public void DoFunction4(bool input)
{
_logger.LogInformation(input.ToString());
}
}
Cocona takes care of handing input arguments. As you can see in the Code above , each function requires an argument of a particular primative type.
If say for DoFunction3 I wanted to make the Datetime input optional, I could simply change the type to a Nullable Datetime.
app.AddCommand("function3", ( [Argument] DateTime? dateInput ,IMyService myService)
...
public void DoFunction3(DateTime? input)
{
if (input.HasValue)
{
_logger.LogInformation(input.Value.ToLongDateString());
}
}
This is not restricted to primitive Types. In the documentation, there is a demo that uses the recently add record class
What is also nice is that if you try to run the Console app with no or invalid arguments. Cocona will generate Help and suggestions automatically
If you do not need or want to use the Built in dependencies. There is a Lite version of Cocona which excludes the Microsoft.Extensions.* dependencies.
Summary
I have only scratched the surface of the features here. There are a lot more features such as Sub commands, Input Validation using System.ComponentModel.DataAnnotations, Customizing the Help and Localization.
I hope you can see that Cocona can give you a great out of the box start when writing a console app.
So please go and check out Cocona for yourself and if you like it, Please consider giving the Repo a Github star.