This is Best Way To Create CLI Apps in .NET

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody I'm nian in this video I'm going to show you what I think is the easiest and simplest way to create CLI tools or command line interface Tools in net with C shop and not only do I think this is the easiest and simplest but also the most elegant way to do it because we can actually structure our project in a way that is very familiar it doesn't feel like a special thing even though it technically is it's a CLI tool it just feels like any other net project we're familiar with and in this video I'm going to explain why that's the case and what package allows us to do that if you like L content and you want to see more make sure you subscribe for more training check out my courses on D train.com okay so let me show you what I have here I have this console application doesn't really have anything and traditionally if you want to make a CLI tool all you do is you'd pass the arguments array and you'd say that the first thing is maybe a command argument the second is an option the third is whatever or you would use a new package like the command line poser that gives you some form of functionality to make a CLI tool however the package I'm going to be showing you today in my opinion does this even better because not only does it support dependency injection logging configuration environment variables in a familiar way out of the box but it also feels like a net application like the ones we used to if you made any net app in the past two years You' feel right at home with this and it feels very very natural this package is called kokona so I'm going to go ahead search for kokona and install it I've actually showcased this package a long time ago and I said it's one of the five underrated projects of net since then it has grown so I'm going to put a link in the description if you want to give it a start on GitHub I think it's an excellent project that you should be using if you're making CLI tools and the simplest way you can make a c tool with Kona is say kokona app.run and then you can have this delegate over here and in the delegate you can say console. rideline hello world and that is it so if I go to the terminal I can say net run and I'm going to get hello world now you might think wait I could do this hello world even without kokona why do I need kokona well you need it because now you can also have in that delegate parameters in the same way in a minimal API you would have parameters in that delegate and you can get the name and you can say hello and now grab that name so what I can do now is go to the console say Don netrun and pass the option name and as you can see now I say hello name name I wanted to say Nick so I'm going to say Nick but as you can see I'm getting the name now by default that name is what we call an option in kokona meaning I have to name it it is this one and I can give it an alias as well if I want to so that would be something like this if I want to be um n for example to pass the name I can do the following I can say n remove the double hyphen and say name is Nick and you're going to get hello Nick but I can also have in Kona what's called an argument and I don't have to name it it will use the name of the parameter and if I do that I can go here and say remove this and this option and pass it as an argument it is the first one it is Nick so I have a couple of options to pass down things and I can use both so if I wanted to have the argument here and then the option of the last name for example by default if this is not nullable it's going to be mandatory so I can go here and pass it down and if I don't provide it it's going to say hey you're missing the last name option but if I go ahead and say last name is chaps say I can do that and we're going to get Nick chapsas now if this was nullable I can go here and say that this string is nullable return back not provided and we're going to get that printed anyway because if it's not nullable it is optional not only that but in the same way that in the net CLI for example we have the help command that lets us know what options we have available to us what are the arguments what are the options I can have the exact same thing in kokona so I can go ahead in my argument and say that description is the first name and then in the option I can also have a description and say the last name and by default I get a help command that can go back and say net run go into command mode and say help and I'm going to get the help description of the tool which in this this case is arguments name the first name required options last name String the last name so we get that sort of behavior out of the box now that's great and all but that doesn't really look like what I made it appear to be which is something that looks like a net application most specifically an aset core application well we can do that by getting first the Builder in the same way you would get a builder in aset core by calling the web application at. create Builder now we're going to say Kona app. create builder then we're going to get our app by saying builder. build and then we're going to say app. run does this sound familiar because it is it's exact same model you would have in a minimal API structure or in a web application Builder structure and if you want to get access to di container you get in the same way you have your services you have your loging host environment and configuration everything you already know how to use works here now let's go ahead and bring some weather logic into the API now before I move on I'd like to let you know that we just launched our second clean architecture course on D train called Deep dive clean architectur in.net and it's again expertly delivered by Microsoft engineer Amai manman who also has YouTube channel and he's also running clean architecture training for Microsoft employees within Microsoft this is a unique opportunity to learn how to build applications using clean architecture by someone who writes code for Technologies like thems PowerPoint and word and his code is used by millions millions of users every month not only did we launch this course which is a followup to the getting started we already have but now both courses are bundled into a from Zero to Hero clean architectur in. net bundle which also has a permanent 20% discount so if you want to buy both that's the best value you're going to find Now to celebrate the launch I'd like to offer the first 500 of you a 20% discount on this brand new C so check the link in the description and use code clean 20 at check out this is by far the best architecture course you're going to find out there everything updated to latest.net with latest practices by someone who's actually practicing what he's teaching in one of the biggest companies in the world so don't miss this opportunity now back to the video to do that I'll bring in this folder over here that includes a way to call the openweathermap.org API to get the weather for a city the current real weather and I'm using a real API key to call that now I will need things like dependency injection here and also the ihtp client Factory to generate those clients how can I do that well like I said di works fine and HTTP clients and all that works fine so all you want to say is microsoft. extensions. HTTP and bring in that logic and immediately that error goes away and I can use it meaning I can go to program.cs say builder. services. add Singleton and register the Weather Service as a Singleton I can also say builder. services. add HTTP client and that will register my ihtp client Factory Now by default here I have no commands but I can go very easily and add or map in a way my weather command how well I can use my ADD command method so the command is weather and here goes my delegate so what do I want well to start with let's just get the weather so what I'm going to do is inject the ieather service over here and then get the weather so VAR weather equals await the Weather Service I'm just going to hard code London in here and I'm going to turn this into a sync which I can and all this will work and then I'm going to say console do right line and I'm going to serialize in Json the response which is weather and we're going to pass down some configuration as well just so we pretty print the Jon and that is it and now I can go to the console again and say net run weather and I'm going to get the weather as you can see now I'm also getting some logging out of the box as you can see and a few warnings that are relevant they're build related but this now works and I can also use the command syntax that will also give me the exact same result which is I'm getting the actual current weather for London right now which is amazing now of course I would want to add an option for London the city so by default if I say City over here this is an option and I can take this option and pass it down here and because it's not nullable it is mandatory so if I just try to do the same thing it's going to say hey optional city is not passed you have to pass it down so City London and I'm getting the weather here I can do city um Paris for example and I'm going to get the weather for Paris and so on this is the real weather as well now a few things I don't like I don't like to have the logs of the HTTP client Factory so what I can do here is I could either bring in an ABS settings. Json file to customize the logs or since I have access to the loggers I can just say logging do add filter specify the category and say that I want this to only bother me if you have a warning or anything higher than a warning and if I do that and I do the exact same thing in the command I don't get all those logs anymore all I get is the response and that is it now all that goes way deeper and normally you wouldn't really have that command over here what you would probably have is you would organize those commands in their own files for example I would have over here a weather command or a weather file or class and I would have this logic here how well I can have the following I can say public async task over here and I can call a method weather so I'm going to leave it as it is for now and then what am I doing here I'm injecting the ieather service well I can do that in the weather command class so I can say private read only pass down that parameter and inject it through the Constructor and then I can use it to do whatever I want in my weather method so what was I doing here I was just calling this serializing it and then pasting it or printing it in the console so I'm going to do the exact same thing here I'm going to do the exact same thing with the parameter again I'm going to have the city and then the serializer so I'll comment all of this command out with not going to need it anymore but if you want to grab it from the code down below you can I'm gonna leave it here for you and now what I'm going to do instead is say app do add commands and I'm going to add the weather commands as a class over here as a type Now by default because this is the only method in this class any name it will actually work here to get the weather I can say a whatever weather and I'm going to get it however I have two options here for example first I can say that this is a command and the name of the command is weather the moment I do that I can change the name of this to be whatever I want and if I try to call that method again it's going to say I don't really have that command but if I use the weather one we're going to get it also if you have multiple methods for example here and you don't have the command attribute and I can say weather one and weather two then what's going to happen is the name of the method will be used as the command so it will be assumed that both of these are commands to show that I'm going to show you that if you do weather nothing happens the similar commands are weather one and weather two automatically detected by the way and then I can say weather one to get the weather and get it to to get the weather again all that works of course you can use the command attribute to overwrite the name or you can even ignore any commands if you don't want them so now weather two is not visible if I try to call it I'm not going to get anything here this approach in the structure that allows us to inject things and also have the commands detectable of automatically not only does it make it very easy to structure and work with but also very testable because now we can easily mock everything that we need and not we can write reliable unit test for application now there's more things you can do with nested commands and sub commands but I'm going to leave you with this because this sets all the right foundation for you to take this anywhere the basic approach the structure is very very simple but it is so so powerful and you can lift and shift literally things you have in your ASP cor applications into a kakona app and it will work because of how the structure works and how the interfaces work I think it's an amazing project that everyone should give a go and try and also give a start on GitHub but now I know from you how do you make command line applications and do you make them in the first place I know I do for things like control these lights over here or things in my house but what are you using them for leave a comment down below let me know well that's all I have for you for this video thank you very much for watching and as always keep coding
Info
Channel: Nick Chapsas
Views: 63,256
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, .netcore, dot net, core, C#, how to code, tutorial, development, software engineering, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, dotnet, .net, c#, cocona, commandlinetool, commandlinetools, .net command line tools, cli tools, .net cli, .net cli tools, .net sdk, The Best Way To Create CLI Tools in .NET
Id: 4KHFrbJHCHc
Channel Id: undefined
Length: 13min 23sec (803 seconds)
Published: Thu Dec 28 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.