.NET Core Console App with Dependency Injection, Logging, and Settings

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
dot net core has brought a lot of great benefits right into the dot net language we get dependency injection a much better configuration system and we have common logging systems that are easy to use the only problem is that mainly we only see these things set up for us in a web environment what happens we want to get these things running in a console application for example well it takes a bit more work but it can be done in this video we're going to set up dependency injection configuration using appsettings.json and logging using seralog in a console application now this is your first time watching one of my videos welcome my name is tim corey and it's my goal to make learning c-sharp easier every monday i teach you something about c-sharp code and every thursday i work to answer your questions we'd love to have you subscribe the channel and enjoy with us as you watch now i take comments very seriously so if you have questions or thoughts about c-sharp code or want to know more about a certain topic leave that down in the comments below i will read it i will get to it it's taking a little bit longer to get the comments just because it's there's so many of them now but i am working very hard to get to all the comments and at least read through and write down my suggestions and put on a list and then what i do is i look at my list and say what do people need and then based upon that i created a video for it this video is an example of that i've had numerous people say you know dependency injection is great in net core but what about console apps that are.net core so if you have thoughts leave them down below and i'll add to the list either way thanks for joining us all right let's get started in visual studio we're going to create a new project i'm using visual studio 2019 community edition that's the way i install and reinstall my pc and we walk through that process so that's what i'm using so it should be about the same as what you're using right now so console app for dot net core this is important because there is also a net framework version of the console application we want net core version notice this runs on not only windows but also linux and mac let's call this console ui and we're going to call this better console app the solution name and we'll hit create so it's going to create for us our project and solution that's a dot net core console application now right out of the gate you get what's pretty similar to an you know what we are used to in.net framework which is just a static void main and then you can write whatever code you want in here and typically if we're honest most of us put all of our code between these two curly braces and don't put code anywhere else because that's just kind of how we do things but we really want to go a little bit beyond that and say yes this is a full application let's treat it as such and let's make sure we're writing applications that are easier to maintain easier to upgrade and improve without redoing the entire application so let's add things like dependency injection and logging and a configuration file can change at runtime so the place to start here is in nougat so right click on dependencies and manage nuget packages we're going to browse here and we're gonna look for microsoft.extensions.hosting that's this one right here this we want to set up our hosting environment so we hit install here and we hit okay i know the fonts mess this up a little bit but it's saying hey we're gonna make some changes to your solution is that okay yes it is and i accept the license agreement so that's one we're going to add a couple more actually three more for ceralog now if you're not familiar with ceralog what this is is it is a an alternative to the built-in hosting or logging system in net core it's an alternative that i think is much much better because it gives us a lot more options and flexibility the built-in version of logging is really just the starting point it's the the place you kind of kick off from and say okay if you're just doing basic logging this will work but for anything else you probably should add something different and so sarah log is that something different allows us to log to a number of different platforms whether it's sql or whether it's text file or whether it's console or wherever and today we're going to do console just to show how it works but serial log is kind of like almost it's almost required if you're going to do any type of quote unquote real application now the same is not necessarily true for the dependency injection system i use the built-in.net net core dependency injection system for even production apps it's a little bit higher level but if you want to replace that as well with something else like auto effect or another one you can do that just as easily but for us today we're just going to replace the logging system that's a much more common thing to do so i first add ceralog.extensions.hosting so this is for net core logging and hosted services we hit ok and i accept and we also want to have seralog.settings.configuration and that's going to be to talk to the appsettings.json file to get its configuration i much prefer this to hard coding my logging setup so this is where i put in appsettings.json the information about how to configure our logger so let's install that let's check the box that don't show us again okay and one last one and this is ceralog.syncs.console and what this is a serial log sync is the place to log to this is the the location where you want to send your logs to so in our case we're going to send the console it's also the colored console meaning you could actually change colors for your logging or to a file or to a rolling file application insights elastic search there's so many different syncs that's one of the benefits of ceralog is you're not limited to just a few different places to log to you can log it pretty much anywhere and so in our case we're just going to choose console but later on you can add different sync in and you're all set up basically you're just ready to go to use that other sync in that other location as well for logging let's log to the console and that's it so those are our nuget packages now i'll show you a little trick here this is newer with dot this is new with dot net core it's it used to be that the cs proj file the project file for c-sharp was something you could not edit unless you were offline meaning you had to right click on the project and say unload project in order to edit the cs project file but now you don't have to and with that it we also get a much much cleaner cs proj file it used to be get oh between 150 and 250 lines of of text in your cs proj file now we have a much much cleaner cs proj file in fact this is mine it's 15 lines now i just started a console application so there isn't a ton anyways but what this shows is this right here i want to point this out this is my installed nuget packages known as item group package reference a package reference means a nuget package so there is the packages i have installed if you wanted to create a new console application and you want to bring those four packages in you could just copy this group and go into the new cs proj file paste it in and now it'll bring in those project files instead of doing a nuget and manually entering those four references so it's a neat little shortcut there and one that makes it a lot easier to create projects that are very very similar or the same starting point even if you don't create a project template which you could do so just note that's there so now we have our nuget packages installed let's now add our appsettings.json file notice there is none currently because we don't have one for console apps by default so right click on your project and say add new item and we're gonna search for json json and choose a json file and just name this app settings noise is plural there and this name is important so appsettings.json i didn't give an extension but since i selected json that file type it gave it a dot json by default so appsettings.json this is where we'll store all of our information so the other thing to do here is right click on it and go to properties and you want to set the copy to output directory notice this one right here you want to set that to copy always or copy or it copy if newer it's up to you what you do i prefer to copy always just to make sure i have the latest version and if i have an application that changes the app settings.json it's going to get overwritten every time i do a rebuild so it's not confusing so that's my preference but you need to make sure you do that if you missed that step then you will not have an app settings.json file to use when you're trying to run this application and it may be confusing all right so we have three goals for this system let's put up here we want to use dependency injection or di we want to use logging let's just say serolog because we don't use logging but with seralog and finally we want to use our settings okay those are the three things that this console app needs to do so let's start by hooking really all of these up together there's not really a way to pull apart and say okay let's just hook up just this one thing and add more i could have done that but it would be a little more confusing than helpful so i think we're going to do it all at once and then we'll talk through different pieces okay so let's start with this build config so with logging we want to log right away before we even set up depends the injection properly before we even do anything else and so we're going to do is we're actually going to talk to the app settings.json before it gets set up in its natural occurrence we have to actually create a manual connection to app settings.json to do that we're going to say static void by default private static void whereas say build config it will pass in i configuration builder all right now notice when i did that this is a newer feature in visual studio 2019 you may or may not notice it but i didn't have this using statement here but since it knows that i might have use of it then it's kind of it's telesense it's kind of kept that in the back of its mind saying hey um you don't have this install or a using statement for this but you looks like you're looking for that so i could go ahead and add that using statement so it's kind of a really intelligent way of doing things but just know i did add that using statement up here just by typing this out so if yours doesn't do that you might have to do a ctrl dot and add it i'll show you that right now so if it's not here and i say let's call this builder and it says hey uh you got something wrong here if i hit control dot it brings up my quick actions and refactoring and the first one is a using statement for microsoft.extension.configuration i click that and it adds that using statement at the top so that's the the manual way of doing that if it didn't do it for you automatically i really don't i have magic in this i'll make sure i point those things out all right so with this build we're going to pass in an eye configuration builder and this may be confusing i understand that we're going to explain all of this but some of it has to be down in you know on paper but it's you know in code actually written before we can talk through what it does otherwise it's just theory i don't like theory either so let's just do this and then we'll talk it through so builder dot set base path to be directory dot get current directory again that add the using system.io let's go to the next line and we'll say dot add json file app settings dot json and optional is false and reload on change is true now we could stop right there and what this would do is it's going to create or add to our builder the ability to talk to appsettings.json now where is that appsettings.json well it's saying hey wherever you're running mr exe or ms.exe look in that same directory so the current directory where you're running look for an app settings.json and add that as your settings file and that's not optional if the app settings.json file changes reload it that's what that's doing so that's that's creating a connection to our app settings.json file we could end it right there but we do want to have this ability that we already have with apps.json files which is to have an override for the development mode or for production mode or others so let's add another json file called let's start with a string interpolation app settings dot and then our curly braces environment dot get environment variable asp.net core underscore environment make sure you spill it right all right i'm going to unpin this here so what's this doing and we're not done yet but what's this doing well what it's doing is it's saying i want you to get not just appsettings.json but appsettings.development.json or appsettings.production.json whatever mode you're running in i want to get that environment set as well because with appssettings.json you can override and i'll be doing a video on this in the future i've already covered it in some of my courses i want to do this for youtube as well where we talk about just how amazing appsettings.json is you see we used to have app.config or web.config so for a console we'd have an app.config file and that was a place we could put all of our settings but what if you have a connection string that is secure what do you do with that well you'd put it in a different file and then you try to kind of inject it during uh during build into your app.config file which usually use that tool like slow cheetah to do that or something else but you're still saving a file somewhere it's a little messy well now with appsettings.json it's a whole lot easier there's a whole hierarchy of different settings files that override each other kind of like what css does where depending on the order it one will override the other so in this case this is the starting point app settings.json but if you have an app settings dot let's say development.json file that is going to be different than appstage.json and you're in that environment then it will override that setting so in this case we're going to say environmental variable but if it doesn't exist then use production as our default and then put json at the end so app settings.development if we're in the development environment but if we can't find what environment we're in then default to the fact that we're in production that's the assumption is if it doesn't specify it it's production and lastly we want to also mark this optional equals true because what if you don't have that file which we don't have that right now no problem it's optional if you don't find it cool don't use it but then you also want to add environmental variables so if you have environmental variables they can override what's in appsettings.json so maybe you have a environment variable that overrides your connection string so on your pc it's this connection string but it's not like you put that into source control because the default one is you know a throwaway one or something like that and yours locally is specific to your local machine so that's why you might use an environmental variable so this sets up our talking to a configuration source all right like i said this is going to happen before it normally happens in the setup process and that's to allow us to do logging before we actually work with our configuration does that sound confusing i hope not but it probably does and that's okay we're going to get to it so let's start in our static void main let's kind of highlight or minimize this just because we we saw the code does now i just rely on build config we're going to call it that so var builder equals new configuration not binder builder so i start off a new configuration builder which just happens to be an i configuration builder which means we can say build config on our new builder to create a whole new configuration builder and we've said hey you know what once you go ahead and add the the app settings.json stuff to it all right now i didn't get that builder back i just pass it in but remember with objects in c sharp we pass references now with with types like an integer or a boolean we're copying a value but with types or i'm sorry objects we passed the inst we passed a reference to that instance so whenever you do a work on builder even if it's in build config it's going to modify the builder for everybody all right so now that it's modified we can set up our logging for serial log so log notice it says over here serial log it's going to add a using statement at the very top so i hit log dot notice now we have a serial log reference up here log.logger equals new logging configuration logger configuration sorry that's why i wasn't showing up logger configuration now i am going to do a dot read from configuration builder dot build what it's doing is taking that builder and saying okay execute that builder which means it's going to set it all up which is going to give it connection to the app settings.json file we're going to read the configuration from that resulting build so it's going to be able to talk to the app settings.json file now plus the appsettings.developer.json or appsettings.production.json plus the environmental variables so the logger can now read the configuration from the appstains.json file which won't have any in there yet but we will all right and that allows us to set up all our configuration for serolog in our app settings.json file and i'm going to say dot enrich from log context and that adds extra things from serolog so it gets more information it says enriches from log events with properties from the seralog.context.log context okay so that's gonna add extra stuff to our logging and then afterwards i'm gonna say write to dot console this is really nice how they've set this up because it reads very cleanly we're going to read from we'll get ready for the configuration we're going to enrich it with log context we're going to write it to the console and then finally say create logger so that's our logger that's how you set up ceralog is we first have to establish a connection to the configuration file if you're doing configuration setup for ceralog and i do encourage that and then we say here's the setup work for our logger so all that work so far was all about ceralog and get our logging configured properly we're not quite done because we do have to set up some configuration in our app settings.json file but we'll get to that after we've finished in this this file here now we're ready to actually set up our console to have dependency injection logging and talk to appsettings.json because even though we have this build config that talks to app settings.json that's kind of a i want to say a hack but it's almost because that's you know that's do it before the natural process of things and we have to do it because we want to set the logging right away because we might actually want to say right here log dot logger dot information where you say uh application starting something like that so it's gonna log information saying hey we're starting the application now so just note that that's what that's for but now we're going to set up our our actual way of doing dependency injection and all the rest so var host equals host so capital h host dot create default builder and this one's yelling me it's saying no no that doesn't exist in the current context so let's control dot on that and use the using microsoft.extensions.hosting so it didn't add the using statement up here that we needed for this because wasn't sure what we were doing it's okay we can add that using statement so now it's it's up here and now we're all creating this default builder this is really cool i really appreciate microsoft doing this people keep saying to me oh you know microsoft documentation is so bad and for so many years that was so true but it's getting a lot better i mean docs.microsoft.com actually reads like a book it's great and even in their code they're getting a lot better instead instead of saying what does the ilogger do it logs stuff there's a little more explanation than that well create default builder what does this do we'll mouse over it here's what it does here's the final defaults that are applied sets the i host environment content root path to the result of directory.getcurrentdirectory it sets the i configuration with the net underscore prefix environmental variables then the i configuration from app settings.json look familiar and appsettings.environment or ihost environment dot environment.environment name which would be development or production so appsettings.development.json and then it also loads eye configuration from user secrets i host environment.environment name is development using the entry assembly and it loads the eye configuration from environmental variables so it's setting up the our hierarchy our default hierarchy for eye configuration which is we're going to get stuff from appsettings.json but as you notice so many more places including user secrets and environmental variables it also configures the i logger factory to log to the console debug and event source outputs which we're going to override today and then it enables scope validation on dependency injection container when the environment name is development so that's all the things that this does and if we just do the create default builder it will do all those things just as is but we want to add more to this the first thing you want to add is a place to put all of our dependencies so dot configure services and we have two open parens and we're gonna pass in two values here i'm going to call them context and services and then we're going to do our arrow and our curly braces so in here is where we configure all of our services if you've ever created a asp.net core project you'll have a configure services section it's the same thing as this all right so we're gonna put in here any of our services we don't have any yet but we're going to create one really soon so i'll leave that blank for now we're going to come back to it and then after this i'm going to say dot use ceralog that's it because we've already configured ceralog right up here so let's use it and then finally dot build now notice i'm using the the ability that that c sharp has to do multiple lines as long as you don't use a semicolon so i've said okay this line and i have dot this is all chained together but because i wanted to be more readable about it i put on multiple lines just like i did up here with this lower configuration this is a pretty common thing to do when you have these chained methods so believe it or not we're actually done configuring everything for dependency injection app settings.json or or settings settings and for logging we're done this right here does everything except for setting up ceralog which sarah log is extra if we want to do serial log we want to use the default logger then that would be all we need is this this little section right here adding ceralog adds this information and this information now let's create a class that we can put into our services and actually call remember that with a console application we call the static void main we start here and we get to here the console closes so we need to in here somehow activate a class and call that class to do something so what i'm going to do is create one class as my entry point that kind of replaces the static void main where i have a run method that when it's done running then my console is done let's create that class i'm going to create it right down here after this curly brace now i do not encourage you to leave classes inside of other files so don't have multiple classes inside one file but this is a great place to create a class and then move it and i'll show you how to do that so public class let's call this greeting service all right and this is going to have a public void run method and this method that's what i'm saying is this method will replace what we'd normally put inside of static void main and it can do all the calls that it needs in our case it's a really simple it's just going to do a for loop and we'll say i 1 to 10 for right now we're going to change that in a minute and we're going to say hey i want to print out you know this is number whatever number it is but i want to log that not just just write it out to the console i'm going to log into the console because we're just doing a console logger for now but this is just to show that we can use logging okay so how do we get logging in here and also that 10 right there seems like it should be a more flexible number meaning maybe you want to change that over time maybe we'll pull that from configuration instead so let's set up a constructor for this wow we have one too many e's here for this greeting service so ctor which is a snippet for constructor that creates this constructor right here greetings service i'm going to say i want an i logger i want i logger of type greetingservice call just log and then also an i configuration of type config or name config so i logger ctrl dot here to add the using statement they may say tim why you have a logging type of greeting service well with ilogger we can pass in the type that it is and that will send that information on to our logger so our logger knows what type of class we're getting a call from now i need to store these two pieces of information so i can use them so first log i'm going to ctrl dot here and create initialize the field underscore log so it creates a private read-only i logger called underscore log now yours might not call it underscore log i just call it log well the reason for that is because i've made a tweak to my settings you go to tools options and down here under i believe it is oh there it is text editor for whatever reason these are not in alphabetical order which is frustrating text editor under c sharp if you go to i think it's intellisense nope code style there we go naming so code style naming so under text editor c sharp code style naming i have added this line right here which is unreadable because of the fact that i'm using a larger font size and so it doesn't grow the boxes with the font size which is frustrating but i'll show you what this is so i've added a new entry for private or internal fields so i said plus here then the first entry is private or internal fields the required style i called underscore because it wasn't already in the list there was pascal case and begins with i so i said manage naming styles and i add a new one with this plus right here i called it underscore and the required prefix i said underscore and then i said down here camel case so i call this underscore i put the underscore here i capitalization is camel case and there is my sample that shows you exactly what's going to look like i hit ok and then i used that in this second the style so underscore and the severity i said refactoring only it's not a a warning or an error or even a suggestion i just said refactor only it's up to you what kind of severity you want to add so that's that's now how when i say control dot for example config create initialize a field it creates that underscore config for me so i like that i have a preference when i'm bringing in information from the dependency injection system it tells me okay don't modify this it's the same thing i use with private backing fields for properties because that way i know hey don't modify this private backing field you go to the front end of the property and you modify it there so you don't not shortcut in the circuit so same way here you don't modify config or log you use them so that's what we're going to do now just to be clear if there was data that was stored inside of log or config you can still modify that data it's just you don't want to overwrite this log with a new i logger or overwrite this config with a new eye configuration instance that's what you don't want to do okay so now we have i logger and i configuration now you can come down here and say you know what let's do underscore log dot log information and we'll create our message so we are um let's just say run number uh run number like so and we'll pass in i there we go so that's going to create for us our log information you may say well tim why did you do string interpolation there why don't you put a dollar sign in front of this and put i there well because in logging if you have a structured logger like ceralog is then what serolog will do is it will not only log this text but it will also log this value separately under the variable name run number so that you can look through your logs and do a query on what does run number three look like across all of my instances versus having a parse string to say figure out which one is number three not number 30 not number 13 just number three so doing so this way actually makes a lot more sense for logging purposes so we're just going to loop through and log all of those numbers but now let's also change this over to pull from our configuration so config dot get value of type int and let's call this loop times the number of top rail loop through this thing which isn't there yet but it will be we go to solution explorer appsetting.json i'm going to say in quotes loop times and let's start with 5. okay so now as five loop times we're gonna loop through now we have our greeting service done we're gonna call this run method it's gonna loop through this five times hopefully and be done let's at the end of our static void main the very end i'm going to do a console dot uh you know what i'm not going to do that i'm not going to console read live because it already pauses for me because of how net's core works a little bit differently so let's not do our console relay at the end we don't have to do that but we do need to call this thing so how do we call it up here in a way that uses our dependency injection system well first we need to add to dependency injection so services that's not it services dot add transient transient means give me a new instance every time i ask for it for the greeting service now those of you who are familiar with dependency injection might say well tim once you want to do an interface of this my answer is yes yes i probably would okay but in this case we're just gonna do it this way ah i hate doing that i hate doing examples where i say yeah don't do it this way in real life so let's do it right so first we're going to move this off into its own file so click on the class name control dot move type to grading service dot cs it's gone and now it's over here next i'm going to come up here on the class name and go ctrl dot again and say extract interface and it says what do you want to extract just the run method that's the only thing that's public i hit okay cool so now i have an interface for this now i can say i greeting service and greeting service that way it's much more realistic to what you'd see in the real world and the reason why you do this it may feel like that interface is a waste because it's just mirroring what you have in greeting service right well not quite because whenever we reference or ask for a greeting service class we're going to ask for i greeting service and when we do that we're going to get back greeting service so what's the benefit well when we're ready to test we can say hey you know what this other class depends on i greeting service but we want to test that so we'll pass in a different i greeting service than greeting service so allows us to take away dependencies or change dependencies to be ones that won't write to a database that won't send emails to customers that won't make changes to production values so that's what the interface allows us to do very easily when it comes to testing is replace those dependencies so even if you only ever have one implementation of your interface you'll still be available to have a second implementation which is for your unit testing and that's a really good thing plus down the road if we say you know what we have a better greeting service you create that class and as long as you implement eye greeting service you replace it with this one with better greeting service and nothing else has to change your application just gets an upgrade so really helpful to use the interface so i encourage it whenever possible to use that interface don't just go right to the class so even though this is a demo i'm going to do it right now that we have that we still need to figure out how do we get greeting service and start this how do i kick this thing off because we want to do it right so we have the dependency injection system using or working against our creating source if we just try to do a new greeting service we have to pass in ilogger and eye configuration which we don't have directly we could probably get them but that seems like a lot of work and it's not how it depends the injection system is supposed to work so instead we're going to say var svc for service equals activator utilities dot create instance of i greeter service for host dot out of host dot services no it says host right here where i say okay you have created a default builder you configure the services you use their log and you did build that's going to build out our our um our i or ihost builder it's going to build it out and put into host so now host has everything it has dependency injection it has logging it has our app settings.json so use that and say hey you've got a whole bunch of services your dependency injection container in those i want you to find or create an instance of i greeting service and it goes and says okay i got these services one of them is i greeting service i'll give you a greeting service instance now that's in this service so this service is an i greeting service so we can say s v c dot run and what does that do it's going to run this right here and it's going to call this loop it's going to loop through however many times you specified in the apps.json file and we can go from there so we're almost there we're almost ready but there's one more thing we have to do and it comes back to ceralog in appsettings.json we promised sarah law we're gonna put some configuration here to tell it how to work so let's do that so i put a comma after my five and i say serial log i'm gonna put my open close curly braces and we're going to say minimum level let's set our minimum levels the default is going to be information oops but we're going to override this and this comes right from sarah log as kind of like the place to start so your override for microsoft to say information and for system we're going to say warning now this comes right from sarah look like i said am i i wanted to put it in here this way just to talk you through what are some of the basic options now i have a whole video on serolog we're not gonna go too deep into that but i do want you to know how this works at a high level like i said you can go watch a ceralog video if you want a more in-depth view but it's saying the minimum level for logging is going to be by default information so if you say log.log information that's going to get printed out to the console which is the only sync we added but if we're override this default value for certain namespaces so the namespace is microsoft.something then information is the override you may say well that's redundant well yeah but if we change the default to warning up here it would still be information down here so microsoft at the information level but for anything that comes from system we're gonna say it has to the warning level or higher because some of the net stuff can be rather chatty when it comes to tell you all the things it's doing for you and if you're not careful you will overload your logs with information you never want to get and this is something that i wanted a quick man to talk about when it comes to logging when you first get into logging you think i'm going to log everything don't do that because what happens is you end up filling up your logs so full that you first of all create a problem with your laws to figure out to do with them and second of all you never read them if you're not going to read or act upon your logs then don't save them there's no point to them in fact they're hurting you so only save information you're going to read and act upon now that read may be as simple as a chart that tells you how often you have this certain activity happen that's fine you don't have to you know read every physical line one by one but if you're not going to use the information don't store it so this allows you to change this at runtime remember that we said that when we do this manually talking to the app settings.json in here we said right down here reload on change is true so whenever you change the apps.json file reload it in the application that's because you're you can be allowed to we want to encourage you to make changes to this file as necessary so what i do is i keep my log files usually on at least warning if not error and higher and so it only logs the errors the only the things that are a big deal and then if i find that there's a machine that has a problem or a website that has a problem or something like that some kind of app has a problem i set the logging levels to be let's say information or higher and then i get a lot more information but in a short amount of time because i want to know more context about what's going on that's when i set to information so that's just a little note there don't always just set your logging to be everything okay so now we have this logging setup this is going to be logging let's go uh the greeting service this is logging information level let's run this application for the very first time make sure nothing blows up it didn't blow up okay it says application starting and then it goes uh oh we've got a problem okay so this is this was my bed but let's talk through this this is a great time to talk through what happens when stuff blows up and this is an often a thing i get in my email inbox or in a youtube comment where people say hey this is not working here's the error message which first of all thank you for providing the error message because the error message is really helpful and so when you provide that it helps me diagnose the problem but i do want you to take a minute and see if you can read through the error message and understand what it's saying because often very often the error message tells you exactly what the problem is so this is an unhail exception it may sound scary system invalid operation exception this will not tell you a whole lot but this message will a suitable constructor for type i greetings service could not be located now wait for a minute a suitable constructor for eye greeting service do interfaces have constructors the answer is no so yeah you're not going to find a constructor for i greeting service i didn't want you to i wanted you to find a constructor for grading service which should be what igrading service is is the type of it okay so ensure the type is a concr is concrete was a concrete type mean it means an actual class instance not an interface and services are registered for all parameters of a public constructor so you have to have a concrete type and all the services that that concrete types constructor asks for need to be registered alright so this is because i said i greeting service instead of greeting service now normally when you ask for depends act dependency injection to give you an instance you want to use the interface but in this special case we're starting off the application we ask for the actual concrete type which is what it will start off things with but it will still use the services to populate the constructor for things like eye logger and for i configuration so that's my bad but normally you'd ask for an i grading service but just not in this activator case let's run this again all right so not quite what i expected but we're getting closer so you know the error is yet well the error is actually in my spacing i like to have spacing around things but you can't do that when you do a structured log let's try this one more time and this time we should see run number notice the the color changes 0 1 2 3 and 4 are all in this purple color that means this is actually an object it's it's not just part of the string it's an object okay so we've got application starting then we've got run number one two three and four so it's logging five total runs from zero to four if i go to my app file and change that to 15 and i run this again this time i have 0 through 14. now what if i go to my app settings.json file and say you know what i want this to be warning or higher by default well he run this now it seemed like nothing happened we're just waiting here to close the application that's because none of our messages rated that high if we change this to log.error then we'll see that our messages do show up because they're errors which isn't quite right they're informational but that just shows you how to make sure that you limit your logging to only certain log statements so now we've seen in program.cs this actually this right here this is setting up everything to do with dependency injection that's right here logging which is either by default or if we change our serial log and our app settings.json which we haven't changed at all so this right here sets up all three of the things that we're looking for now we add on the ability to do the configuration here and the configuration right here for ceralon and by doing so we really elevated our logging game for our console application this does seem like a lot of code for a console application however if you look at this and you say you know what all of this is pretty much just boilerplate this is just the standard setup which it really is you can copy all of this information and paste it in your next console application and be ready to go in about 15 seconds or you could create your own project template and then just make this the starting point for your next application and then you just modify things like what your app settings that json is going to have in it okay so you can really take this to the next level and be very quick about how this is all set up okay so that's how to take your console application to the next level to add dependency injection to add logging and to add your app settings.json configuration to it all right so it kind of brings us up to the same level as an asp.net core application all right i hope you've enjoyed it if you have any questions if you think about things you want to see differently or change maybe you want to see how we do this in winforms or wpf in the dot net core world let me know in the comments i'd love to to interact with you on that and put a list of things that you're looking for and then maybe one day you'll see a video based upon your suggestion all right thanks for watching if you liked the video give it a thumbs up i appreciate it and as always i am tim cory [Music] [Applause] you
Info
Channel: IAmTimCorey
Views: 173,513
Rating: undefined out of 5
Keywords: c# console application, c# console application tutorial, c# console projects, tim corey, iamtimcorey, iamtimcorey console, c# dependency injection tutorial, c# dependency injection code example, c# dependency injection, c# dependency injection example, appsettings, appsettings.json .net core, appsettings .net core, appsettings.json configuration, appsettings.json how to add, appsettings.json in console app, serilog, serilog console, console logging
Id: GAOCe-2nXqc
Channel Id: undefined
Length: 57min 41sec (3461 seconds)
Published: Mon Aug 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.