The NEW Way of Validating Settings in .NET 8

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody I'm Nick and in this video I'm going to show you how options validation or settings validation is changing in.net 8. now dotnet 8 in general has a push towards making.net aot or ahead of time ready and if you don't know what aot is I do have a video on that in the channel and one of those changes involve changing how we're doing options validation in this video I'm going to show you what changed how it will work and how you can use in your own code basis you lack of content and you want to see more make you subscribe for more trading check out my courses on dumbtrain.com alright I'm sure that I have here and I'm going to start with a bit of a recap in case you do not know how option validation used to work so I'm going to go into this example options object over here which has effectively settings mapped to it from the app settings.json so we have the example section over here and then a log level in my case it is Nick but it shouldn't realistically this is a log level like information or warning or something like that and then you have retries -1 is an invalid value but let's say one retry is a valid value and I want to restrict what type of values this object can take if I want to do that what I can say is things like this is a required parameter over here but I can also say things like that this retries parameter needs to be in a certain range so it has to be between 1 and 9. now just adding this doesn't really do anything in fact I can go ahead and just run this API over here and then call it from this calls.http object and as you're going to see everything just works I'm getting log level null and then retries as zero but how is that the case if I have a log level warning and retries one well it's because you need to wire That Thing Up and one of the ways to wire it up is to say builder.services and use the add options method over here so I'm going to say add example options and bind them to a specific section the section is config.getsection and I'm going to say example options dot section name that's a generally good practice now if I do that and I go ahead and I run the API again and I go ahead and I call that endpoint again over here and you're going to see that everything is properly mapped so retries one and warning now a couple of things if this log level needs to be part of an enum you're within the range of a denum then you can say enum data type over here and specify the type of log level in my case so this also adds some sort of validation or boundaries to this parameter however this does not really kick in any validation by default what you need to say over here if you use this approach is say validate data annotations and with that I'm going to change this to be out of bounds so I'm going to say that retries actually is -1 which is an invalid value so if I go ahead and I run this and I go ahead and I call it again it started fine nothing blew up on Startup but when I call it and just as a reminder I am injecting this i options object so I'm requiring it in this hello endpoint then and only then and will this blow up and throw an exception and say that data annotation validation kicked in the values outside the bounds it needs to be between 1 and 9. now what you could also do by the way is you can say that validate on start and if you do that as the name implies when you run the application your options will be resolved and validating will start so your application won't even start if one of those values are out of bounds very very handy feature if you just want to safeguard against some bad values that got in there for some reason let's say your provider just didn't load properly and so on however this is done with reflection and everything around reflection on Startup will cause your application to start slower and the way.net is moving is towards Native aot to shave off as much startup time as possible so for that reason what we got in.net 8 is we got a brand new source generator that generates code to do this sort of validation on compile time let's take a look at how this would work and why in my opinion it is a bit clunky like it could be designed better but let's see how it works so I'm going to remove all of these lines over here I'm not going to use any of that and I'm going to go to the example options object over here and I'm going to create a separate class and that will be a public partial class called example options validator and this will implement the I validate options interface over here let me just make this a bit bigger for you and in this parameter we accept the example options object and that is it now if I just leave this as it is it will say Hey you have to implement the valid date a method over here that actually does the validation but that defeats the purpose of having a source generator so all you need to do here to have the generator kick in is use the options validator attribute and the moment you add that the error goes away and we can actually see over here that all of this code was generated based on the attributes given to the parameters in this example options object now the setup is a bit different if you want to use this approach what you want to do is go and say Builder dot services and use the configure method and we're going to pass the example options object in here and then config.getsection and pass in the section example options.section name here we go but we also need to register this I validate options because that sort of service or interface will need to be injected and used and registered and for that to work we have to say builder.services.add Singleton in this case because we don't really need it to be anything else and have I validate options of example options and then example options validator and that is it and the moment you do that I can go ahead and say run this API now and when I call that endpoint over here you see we get the exception but all this is not based on this reflection sort of Base code but instead Source generated in very very very very well optimized which is one of the biggest benefits of having store generators especially Microsoft written ones because they will do their best to make sure they're as fast and as performant as possible we see that constantly with how they keep improving the old ones like the logging one as well now this is not the only attribute we're getting in fact let's say that this retries option was actually a nested object and we had the example retries options over here and we say retries options and we have a separate class over here example retries options and that has the parameter in it then this means I have to go in here make a top level object over here and then that object contains very tries now if I do that and I went ahead and I tried to run this then Watch What Happens we're going to go ahead and just stop it I'm gonna go ahead and just run it and when I call that endpoint this will actually work we're not going to get an exception that is because the option validation is only written for the top level object so if you have nested objects you have to use the very poorly named in my opinion validate object members attribute which I don't like as a name but it is what it is I don't make the rules so if you add that then you let the validator know that hey there is something in here in this nested object you need to go ahead and validate of course this means you're gonna have to have a separate validator so for that I'm going to go ahead here and say example retry options validator example retries options validator I'm going to save that and that then will kick in I'm gonna go ahead and just run this and if I do that and I call it then you're gonna have proper validation on the nested object as well now the reason why I say the design is a bit weird and I can hear both parties by the way talking about this but I would like the options object to sort of control in a way how it is going to be validated so I would like for this to be the partial class and have the validation related stuff in here now would that be too convoluted I don't know I do believe that having separate classes makes you jump in different locations or files to see what doesn't have a validator and ultimately all of this will look the same you just have a password class that implements the exact same interface with the exact same type do we really need so many different classes that's one of the biggest in my opinion design flaws of Soul generators you have this magic attributes that you don't really know what they do unless you sort of take a look at hey this is a partial so it must be a source generator behind the scenes so it's a tricky one but I'm not mad at this design I do think it could be better and actually in the issue that this topic was worked on you can see that there's different approaches on how this could be done people like Damian Edwards have suggested some options that I actually quite like so I wish the design shifts a bit to make it more developer friendly because now it is more is this is this they sort of live in parallel they can change independently deal with it you know that sort of situation in any case this is a very cool feature that's coming and it's just another step into a fully native aot Apple future so I'm really glad they're adding it and I really want to see more now I want to know from you what do you think about this and will you use it are you even using options validation in the first place because many people don't leave a comment down below and let me know well that's all I have for everybody thank you very much for watching and as always keep coding
Info
Channel: Nick Chapsas
Views: 31,595
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, .net 7, c# 12, .net 8, settings validation, setting validation, appsettings validation, .net 8 settings, .net 8 options, options source generator
Id: mO0fwvnnzbU
Channel Id: undefined
Length: 9min 12sec (552 seconds)
Published: Mon Jul 31 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.