.NET MAUI Step by Step Build

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
having one code base for windows and one code base for ios and one code base for android and one code base for macos is very inefficient so what if we had a framework that allowed us to have just one code base but deploy it seamlessly to those four platforms well in today's video we're going to take a look at one such framework that enables us to do exactly that ladies and gentlemen we're going to look at the world of.net maui [Music] well hello wherever you are whenever you are where am i melbourne australia as usual and when is it it's august 2022 so great to be back here on youtube there is nowhere else i would rather be than a few lovely people so thank you for joining me and welcome so yeah today we're going to be taking a look at dot net maui and there has been an incredible amount of buzz around maui certainly within the last six months from both microsoft themselves and a lot of other content creators so i thought i would take a quick look and see what all the fuss was about so i actually started with one of the microsoft learning paths and i've actually put links to that below it's actually a very good set of resources if you want to learn about maybe outside of this video of course which i would highly recommend you watch as well but yeah the learning stuff from microsoft learning path for microsoft's really rather good as are all the other docs so check out those links below but stay with me here for the video and what we're going to be doing today well we'll cover theory what is my way why would you use it what the other concept you're going to need to know and then we'll move into our build we're going to start with building an api pretty quick section but all fully step by step and then the main event is building step by step on my way app so not much more to say code as usual is available on github and again links are below if you want to download the code and follow along that way and before we start the video just one last thing if you do like it maybe give it a like and if you haven't done so already maybe think about subscribing to the channel thing the little bell and you'll be notified of any new content that i make other than that was sort of quite a long videos but three hours so sit back relax not too much take it in and yeah together we're going to learn about net murray well hello and welcome to episode four of season five and in today's video yeah we're looking at dot net murray and we're going to be doing a step-by-step application build we're going to build a rather simplistic to-do application a to-do list application uh but it's going to be more than enough to get us across the features of dot.net maui so before we go any further let's have a quick look at what you're going to be building and we'll do a quick app demo before we launch into a bit more of what we're going to go through in today's video so i will just bring on to screen a emulator for an android device and without ruining the surprise although i've kind of talked about it already yeah my way allows you to basically write one code base and you can deploy that code base that running app is an application it's not a web application it's an actual native app you can deploy that to android ios windows mac os all that kind of stuff in today's video we're just going to be working with well an android emulator and windows as well so let's just run up the app in android and you can have a quick look and see what it looks like it's pretty simple but nonetheless kind of fully featured it does everything that you would need a very simple to do app to do so you can see here i have three things i need to do today if i wanted to add something else just click on the add to do item and i will say code up uh and mario and we'll take that and save that off and you can see that gets added to our list of to-do's and our to-do's are actually being stored in an api so this application is actually calling an api that we're going to build as well very simple api and you can do all the usual stuff such as select it and maybe edit it be a bit more forceful so we can update entries and of course we can delete entries so very simplistic fairly straightforward but there's a lot of work involved in actually setting this up now just before i finish my demo what i'm going to do is i'm going to also run up the exact same application uh in windows so it's going to run up as a windows app as opposed to an android app so let me just start that in my instance of visual studio and we'll do all this step by step as we move through the rest of the video we'll do all this and i'll just wait for it to start i'll pull it on to my screen it might start on my other screen it has let me just pull that over and you can see here oh it's gone quite big i'm running at a slightly higher magnification there we go see that um looks slightly different but you know it does all the same things you can select it you can you know yeah do all the same things it talks to the same api you can add it new entry um draw a conclusion [Music] same api same app just running on different target devices windows and android so that's the power of my this is the app you're going to build so in the next section we'll pause a bit and we'll take a look at course breakdown and then we'll go into a bit of theory but we'll do that next all right so this is what we're going to cover in today's video so we're going to begin with a bit of a theory block a block of theory i'm going to go through enough to get us going but this is very much an on-ramp to the main event which is building our application so we'll go through quickly the ingredients that you need if you want to follow along of course we'll talk about what is.net maui and more importantly what is the value proposition of dot net movie why would you use it not just what it is well then look at the standard project anatomy of a.net moby project and i don't know if you're anything like me when you start with a new framework and you first get the you know the new project template up and running i personally like to understand how all that fits together and it's actually a bit different from maybe some of the other.net stuff that you might be more used to there are some parallels but it's sufficiently different that i think it's worth going through it in a bit of detail next we're going to spend a bit of time on talking about the user interface components and user interface concepts within.net money there's quite a few of them and again we'll cover most of those as we go through the build but we'll start to look at them here from a theory perspective first then we'll look at our overall solution architecture we will look at our api application architecture and most importantly we'll look at our mavi app architecture and we're going to use those application architectures as a means by which we can track how our build is progressing and we'll keep referring back to these architectures as we move through so you can kind of see that there is an end in sight the api is going to be pretty quick the my app is going to be much more um spend much more time on that as it's the main event of our video today we'll then move on to the api build it's going to be pretty quick fully step-by-step but it's going to be a very simple api we'll scaffold it up create our model create our db context migrate all that down to a sqlite database and then we'll create our four api endpoint so we'll be using a minimal api template um very straightforward very light api but we'll do everything to support our to-do application with four endpoints create read update and delete endpoints as you've seen in the demo and then the main event of today is the murray app itself so we will scaffold up the standard mobi app project we'll create a model in there we'll then spend some time on our data service which is going to be used by our mobi app to talk to our api we'll then uh produce our first page the list page that will show all our to-do items and we'll have a first crack at a layout and then we will create a new page the detail page that you can use to add and delete to do items and also look at routing very quickly we'll then do some adjustments to our user interface and spend a bit more time talking about about that and then finally we will circle back to our data service and how that's set up and we'll have a quick conversation about http client factory now if you want to follow along with today's video there's not much you need to be honest with you the main thing you really need is visual studio 2022 at least at version 17.3 now this video is made mid august this has literally just come out this final version of visual studio which has the net memory workload so you'll need this version at least and yes you'll need to install the.net my workload and i'll show you where you can find that in the visual studio installer when we come on to doing the build the community edition which is free should be fine for this video if you want to follow along and then totally optional as we're building an api i like to test my api independently of code so i use insomnia to do that if you prefer postman or just want to use a web browser that's totally fine um but yeah those are the only things you need for today's video if you want to follow along all right so what is dot net murray well let's take a look so first of all what does it stand for well it stands for multi-platform app ui or user interface i've somewhat lengthened it i think microsoft just prefer ui and they've played a little bit faster than this there with the acronym but nonetheless that's okay so yeah mary is what we refer to as and yes as it says there is a cross-platform framework so build apps one app and it will run on windows android ios and macos and yeah as it says that at the bottom if you want to run ios on my course uh apps you will need to have access to a mac which i don't have at the moment so we are just running this our app on windows and android very importantly and i did want to mention this again it's used for creating native mobile and desktop applications or apps so it's not a web framework it's not another single page web framework like blazer or react or something like that it's for building apps that run on these endpoints or run on these devices okay so it actually runs on windows it runs on android it's not running in a browser okay and then what do we build how do we build these apps we'll use a few tools but the main components that we're going to be working with today are the c sharp language and um as i pronounce it anyway i think this is how you pronounce it xaml or xaml which i'm not going to say again so i'm going to say xaml which stands for extensible application markup language and we'll cover a bit uh on that a bit later if you don't really know what that is and then finally maybe actually evolved from something called xamarin or more more specifically xamarin forms which i've personally never used but it's the same sort of idea this kind of idea like a cross-platform framework the key aim of my way and this is the kind of value proposition why would you consider using it well as it says that's to enable you to implement as much of your app logic and user interface layout in a single code base so you write one app and theoretically and actually and actually it will run on all of those devices possibly the one thing you will need to maybe just be aware of is the user interface component of that because if you're running something on a huge 4k monitor versus on a small android device there are probably some considerations that you might need to take into account you might want to determine which platform you're running on maybe make adjustments to how you want the ui to render but nonetheless the the code base is the same all right so this is how it works and this is a kind of high level overview of how it works i've taken this from the microsoft docs which are actually pretty good so put the url to those and at the bottom of this slide and also in the description below if you want to take a look at that so to begin with as i said we have these platforms so android ios macos and windows and we have our app code okay and the idea is our app code will run on all four of those platforms now as you can probably see by the massive gap in between our app code and those four platforms there's a number of things that need to sit in between those two in order for that dream to become a reality so the first thing we have is the net mavi layer itself framework itself which our app code sits on top of now being a net framework essentially our dot net application we need a.net runtime so the four applications we have the four platforms we have there need to have a net runtime running on them so for windows it's kind of obvious we have the the.net core uh common language runtime running on that for the other three android ios and macos we have something called mono the mono runtime which is another open source variant of a dot net runtime we then have the dot net six base class library which runs on top of the dot net runtime it depends on a dot net runtime so we need that as well and then finally we have these platform specific frameworks that run on top of the.net 6 base class library and as you can probably imagine stitching all this stuff together enables our app code to run on top of android so the way it will typically work is our app code only really needs to talk to.net maui and then maybe in the case of android let's say we'll talk to the platform specific framework and i don't have arrows representing the rest of it but basically because it's running on top of this ace class libraries model runtime will then talk to android so it's pretty smart occasionally you may want your app code and you may want to do this occasionally you may want your app code to bypass moby completely and just talk to these platform-specific frameworks but the takeaway from this slide is basically yeah one one code base sits on top of.net maui and then we use these platform-specific frameworks to fundamentally run on top of these other operating systems all right so let's take a quick look at the standard anatomy of a net memory project and we'll also take a look and cover some of the main concepts you'll need to know now there are a lot of concepts here there's a lot of terminology here some of it will land if you're new to it some of it may not land um i feel when we come onto the practical stuff it will make more sense so we'll cover it here so theoretically a lot that will be totally abstract and you might not get it don't worry get anything let me you may not get it first time you'll understand the words coming out my mouth but you might not be able to kind of string all the concepts together into how they all interact with each other but hopefully that will become more apparent as we move through the video so when you set up a or create a maui project in visual studio this is the standard structure of that project and you'll see first of all that we have the platforms folder and inside that platforms folder there will be a folder for each of the supported target platforms such as android and windows and ios and really when we go through the next slide which is basically the startup of the mavi app this is where all the apps begin their life and there is platforms uh native initialization code in each one of these folders that really kicks off the app starting up and what each of those bits of native code actually do is they call the createmowi app method inside our next file down here which is myprogram.cs and this is almost analogous to like the program class in the classic.net core application it's just called maui program in this case and yeah it's the starting point that creates the app um yeah it's called by the platform native code and it's where we do things like register our services for dependency injection okay so if you've as we build our api which is not my app you'll see that we have a program class and if you're more familiar with that it's kind of analogous to that but we'll cover it in a bit more detail as we move through the rest of the video have a resources folder it's fairly straightforward that just contains things like fonts and images and other assets that are used by the platforms by the app so we're not going to work too much with that but i'm just calling out that's what that is we then have app.xaml and app.xaml.cs and this is a common pattern that you'll start to see emerging and the next few things we're going to look at you'll have a xaml file and you'll have a code define a code behind file which is a c-sharp code file so our xaml xml app it defines the resources that the app is going to use amongst other things and the app xaml.cs file is yes as it says the code behind for that particular file it defines the app class representing the app at runtime which is created in the previous step and then creates an initial window and assigns it to what we call the main page property again throwing a lot of words there you're probably going what is that but we've got a few more slides that string it together and hopefully make it make a bit more sense so that we're fun and incidentally should i say we're not actually going to touch either of these files in this project we just leave them as is okay so if that helps you you don't really need to worry too much about it in this video anyway next is app shell and appshell.cs or actual xaml.cs in the zao file we define the main structure of the app and as it says there the memory shell provides features like overall styling navigation routing things of that nature and the code behind file is where we will define our roots so we're going to create another page we're going to create a route to that page again probably seems very abstract to you right now and we will make some minor adjustments to these files in this project but not too many and then finally as far as the standard project structure is concerned we are given a main page which is like the launch page of our app so when we create a new memory application there's just a very simple app that allows you to click a button an account or increments we get given that we're going to re-purpose that page for our to-do application and yep as it says there the actual xaml page is responsible for the the main layout as well and the cs page the code behind page is used for things like event handling so the xaml will um present a button onto that page with an event handler the event handler actually resides in the other file but we'll cover that a bit later so just to kind of flip all that on its side taking roughly the same information and just kind of re-represented it so in terms of start-ups so this is the steps that go through that we go through when a standard mobi app starts up so we start with our platforms i think is already said with the initialization code relevant to each platform and whatever platform happens to be running that will then call the create memory app method in our my program.cs file okay and responsible for setting up the app adding fonts registering services for dependency injection the app xaml and appsxamlcs is really responsible for defining the app resources defines the app class itself represents the application at runtime and it then creates an initial application window or shell okay and that's where the next set of files come in the shell defines the overall app ui structure overall styling and i think of it more really as defining the navigation and routing of the app okay so i don't even think of it almost as a visual thing i think of it more as a navigational type thing although it does impact the visuals of the app and then finally we get our main page presented to us in whatever platform we are choosing to run on and that will have whatever app code we choose to present and again it's within the app shell stuff that you specified what is the main page what is the launch page that you want to present to the user and hence we get main page in this case now what i did want to do just before we move on to some more user interface concepts and there's a few more i'm sorry about that but it does get a bit more deeper than this the things i've circled in red are the things that we are going to touch in this app build and we're going to do other stuff as well as this but just in terms of the standard out the box maui app these are the places that we're going to make changes so we do actually have to make a little bit of change in the android space i won't mention much more about that now we'll cover it later we're going to register a couple of services in our my program cs class so fairly straightforward dependency injection stuff not doing anything with apps ammo or app xaml cs you'll be pleased to hear we're going to make a minor addition to app shell's mlcs where we create a route and then most of our work is going to be done within the main page we're going to completely scrap what is there and rebuild it and we're going to create another page on top of that and we're going to create a data service but again in terms of the standard out-of-the-box stuff these are the only places we're going to make any changes all right so let's just come on now to talk a little bit more about some further user interface components so what we've gone through so far just to structure over my app now we're going to look at when we start building our memory app and specifically when we're working with pages there are going to be some concepts we're going to go through now that you should be aware of and again if it doesn't all land don't worry it will as we do the practical stuff but i want to just cover it here just to get you thinking about it and get you familiar with the terms and reference back to this slide possibly as we do the code build the main thing i want you to take away from this next bit is the hierarchy that i'm going through so if you don't really get anything else just remember the hierarchy of these things and you'll be in a good position so some of these things you've already heard of some of them may be new to you so the first thing we're going to talk about is the shell which we kind of covered in the last slide we'll talk a bit more about that in a second we then have this concept of pages and again i think a page should be fairly straightforward concept we'll elaborate what it is in a minute but in terms of hierarchy shell then pages underneath and you could have more than one page and again it will just label the point this is not a web app it is a native app okay but we still have this concept of pages but then something called views in my way and this is where i think it may get a bit confusing especially if you've done things like mbc model view controller these views are not the same as model view controller views they're different okay and we'll talk a bit about what they are in a minute that page can have multiple views within there and then finally we have what are called controls which i think should be probably quite straightforward controls are things like buttons and drop-down lists and even labels they're all controls and then we have this concept of layouts and layouts might be familiar to you if you've done maybe some web app development and you wanted to do like um what's it called adaptive design where things will react to being on the desktop a viewport or a small android device or small ios device you have this kind of adaptive design that's really where layouts come in in dot net movie land but let's just go through them in a bit more detail again the main thing to take away here is the hierarchy so the shell is the single place to describe the app's visual hierarchy okay to describe it it's common navigation experience and it does things that uri based routing i think of it mainly to be honest with you as the place where routing is done okay that's what i think about it as but as as you can see there it's also responsible for the visual hierarchy as well pages as described by microsoft are what they call the root of the ui hierarchy inside the shell okay so i don't this is what i'm trying to get get to i don't really even feel that the shell is a visual component directly i feel the page is the first thing that is displayed to the user although the shell is responsible for spawning the pages we get given the main page which derives from a class called content page we have other page types like a tabbed pages and fly out pages we are just going to be working with content pages as they are the kind of most common type of page and all the content pages is just a page that surprise surprise has content on it views so a content page such as main page will display or typically displays a view and all a view is is a way that data is presented and how it is presented so we're going to actually work with two types of views we're going to work with a collection and as you can probably imagine a collection is just a way to present a collection of data so we're going to go to our api get a bunch of data back and our collection view is going to display that collection in a way that makes sense we're also going to use a table view for our other page which is going to display our page where you can add a new to-do item we're going to use a table to do that so it's displaying the data in a slightly different way slightly different structure and then finally we have controls and layout so again think of this hierarchy shell pages views views can then contain controls so labels buttons things like that a layout is really responsible for the way that controls are laid out okay so controls are positioned in a layout and more specifically a layout defines the relative control position so again i was talking about if you need on web development although i will say again this is not web development you've got this kind of idea of a concept of adaptive design so something looks a certain way on a big screen this is how it'll look on a smaller screen and the layout is responsible for restructuring the controls that you will have on that screen so i'm not going to go into this in huge amounts of detail i've just lifted this directly from the microsoft docs in fact this is taken from the microsoft learning path again this link is in the link below if you really want to learn more about the this sort of stuff uh the microsoft learning path is really rather good source of material for that we're going to cover it a bit in today's video but if you want to really delve into it goes into more detail and i've just lifted this example of the different layout types that you can get from that documentation so this is not my own image that i've got on screen here we're going to work with stack layout so as you can imagine elements are just stacked on top of each other and they are fluid and how they are stacked and we have absolute layouts which we're not going to touch nor are we going to look at flex layouts we are going to use a grid layout as well though so we're going to use both stack and grid and you can see the kind of concepts there as to how they arrange controls on screen and then just to wrap up this section i want to just circle back to xaml versus c sharp you might be a bit confused about how those two things work together if you've not done this type of stuff before so the user interface is typically defined as a combination of both xaml and c-sharp okay the xaml stuff is used more for rendering the visual xaml is markup so again i don't really want to go here but if you've used html before which is obviously a markup language for you know html elements xaml is somewhat analogous to that and if you want to think of i don't want to say the j word but you want to think of javascript as kind of like the c sharp to html you can maybe think of it like that c sharp in this use case is used for more logic based more traditional programming type concepts like event handling code so to elaborate that here is some xaml code in our xaml file and you can see here it's defining three buttons so three visual elements save button a delete button and a cancel button and more importantly they have events that they will respond to clicked events so enter c-sharp so we have this idea of a xaml file and a c-sharp code behind file and you can see in our c-sharp code behind file we have a method there on delete button clicked which is what is being specified in our xaml file so the two work together okay and you can lean on more more on one than the other you could in fact define your entire user interface using c sharp i don't think many people would actually ever do that you probably couldn't do everything in xaml but you can do it the other way for the most part we're going to use it in a in the most usual use case which is have the kind of visual definition in xaml and then have our event handlers and things of that nature in our code behind c-sharp class so some of you will be very familiar with this setup it's used quite a lot in microsoft frameworks and if you're new to it that's how we're doing it and that's why you have these two separations of concerns which actually kind of make sense all right let's move on and take a look at our solution architecture which is probably a bit of a grand term for what our solution architecture is it's pretty simple so we'll move through it pretty quickly so yes we'll start our build uh with a net six minimal api with a sqlite database it will have four endpoints for our create read update delete operations but we're going to keep it simple as you'll see on the next slide when we delve into the architecture of this app but for our purposes totally sufficient then the main event which is our mummy app or to-do app our native app and that is going to run on android and again to label the point we will write this application once and we will run it on at least well two platforms android and that app will behave as you would expect we'll talk to our api and both create data and retrieve data and update and delete data as well and then just to label the point as you've seen in the demo we'll also run it on windows the exact same app and it will interact with our api in exactly the same way all right so very simple solution architecture i don't think we need to spend too much more time on that what we do want to move on to now though is the application architecture of each of those applications and when i talk about application i'm talking about our api and our mobi app so our api first keeping it very simple we'll scaffold up a new minimal api project and we'll get this stuff out of the box we'll get our program class and we also get the middleware as well the request pipeline middleware we'll then start our build for real and the first thing we'll do is create our model or to-do model very very simple super simple we'll then have our db context uh which will mediate that model down to our persistence layer which in this case i've chosen sqlite just to keep it really really simple and yes we'll have our four endpoints that we will have in our program class for create read and update the operations and that will or they will of course use our db context to perform those operations now if you've watched any of my other videos on apis one of my favorite subjects you'll know that this is a very simplified build of an api there are no dtos which i would recommend usually there are there is no repository which i would recommend usually i'm omitting those in today's video just to keep it quick all right this will work for our purposes but if you really want to see how you should build an api check out any of my videos on the channel i'll put a link to one of those videos that might be of interest to you but for what we want to do today our api is a bit of a sideshow it's not the main event and this is perfectly acceptable for what we need to do so moving on to the main event that is our maui application and our memory application architecture is what we're going to go through now so we'll scaffold up a new maui app project and we'll get the maybe program class the app class and the app shell out the box we'll make some minor changes to these as we move through the build but for the most part most of our work is going to be done with our pages and our model and our data service which i'll show you now so we will already get the main page xaml page as part of our standard project template so we will test that to begin with but we will then quickly erase it we'll then create a model which will be used for our internal data and we will of course get the main page mlcs code behind file with our main page as well and kind of very high level stitched together kind of like this then we will create a new page and this is the page that we will use to actually create new to do items or delete or update them so we'll call it what i have on screen there manage to do page xaml and we will of course get the code behind page as well and kind of structured a bit like that and then most importantly or not most importantly but as importantly we're going to create a data service that is going to allow us to consume our api and both the code behind files or code behind code we'll use that data service in order to consume apis and render it to our pages now the one thing i really want to call out here is that the data service and the model aren't really core well they're absolutely integral to this murray app but they're not really my concept so what i mean by that is the data service you could literally actually package that up put it in a separate project and reuse it anywhere else as you could with your model it was super simple and you probably wouldn't want to do that but what i want to say is those two components are modeling our data service they are used they are part of our memory map absolutely but they're not dedicated memory concepts they are things we are using to drive our memory app so really we're talking about app shell app and my program as well as the pages all right we're now ready finally to start coding and let's start with our api all right so we're going to begin the build of our api first we're going to go through this pretty quickly we'll go through it step by step of course but we're going to go through it pretty quickly so i'm running visual studio 2022 at the version i specified at the start of the video i'm going to create a new project and the project template we want is this one here asp.net core web api so i'll select that and click next now just make sure you have the location set wherever you want to reside your projects and we'll give it a name gonna just call it to the api i'll capitalize that t as well all right and we'll click next now just on this we are creating a solution because it's visual studio and the project inside the solution now we are of course going to create our murray app as well you could have the maui project inside the same solution i'm not doing that in today's video i'm going to have two separate solutions with two separate projects that's just personally the way i want to do it keep it separate that's the way i like to do it but if you want to put the two projects under the same solution you can choose to do that just a little bit housekeeping there so yep let's go to the remainder of these options so make sure the framework is.net six which is required for this video no authentication we are going to configure https no need for docker this one's probably the most important thing on this particular window here is we want to untick this we do not want to use controllers we want to uncheck and use minimal apis as that's the pattern i want to use it's just quicker and we don't need open a api support which is just the swagger type documentation stuff that you get so pretty simple all you really should have is https enabled that's it so we'll create that and that will create an empty project for us fantastic and as you can see here it's pretty lightweight if you just open up this you'll see this is the the pretty much the bones of it everything else is just kind of support stuff and in fact we're going to take most of this code out but what i do want to do is just check that it's all working there's no reason why it shouldn't but let's just try anyway so click start and that should start up our api and you can see down here that we have it started it's now listening on these two endpoints one for https on port 7209 and one for http on port 5209 so you'll see started on my other screen here that it's opened up the https endpoint and gone to this particular endpoint here weather forecast and it's just brought back randomized weather data so that's all working quite nicely so just killed that um and we're going to get rid of most of this code so we're going to take out this record delete leave in the app run stuff we're going to take out this endpoint we will be creating our own don't worry we're going to take out this range of summaries we don't need that i'll come back to https redirection in a minute but i'll take out these other remaining comments leading in the other two lines all right so pretty minimal uh set of code there ordinarily i would tell you or tell you i would suggest that you leave that in and all https redirection is doing is if you hit the http endpoint it's automatically going to redirect you to the https setting point which is good practice totally recommend that you leave it in usually for nuances that will become a bit apparent later um because we are going to run into some not difficulty but a little bit of config and work around android and accessing things on localhost we're going to use the http endpoint of our api for our android clients you can use https in a development environment it's just a bit more extra work to set up a link to where you can do that extra work i just feel for what we are trying to achieve um it's a bit too much so we're going to use http for android endpoints so because of that i'm going to comment this out you could delete this line i'm just going to comment it out in a production type environment this is not relevant you'd leave that in completely leave that in and you'll always always always use https i'm just doing this just for quickness really all right so before we take a quick pause the only thing i want to do for the remainder of our setup i'll just save that off is to install a couple of package references to support our use of sql lite so a couple of ways you can do it from a visual studio come into tools and you can use the graphical interface so come into nougat package manager you can use this here to search for the packages and install them that way i'm going to use the package manager console instead but i'm going to cheat somewhat in that i'm not going to type in the full command prompt myself just given my typing is terrible these days so i've come over to nougat.org and i'm just going to do a search for sql lite now be really careful i make this mistake all the time it's just one l sql light not two l's so do a search for that um we just want to scroll down a little bit to the entity framework package this one here so we want microsoft dot entity framework core sql lite and very kindly it gives you the different options for installing uh this particular package so you want package manager and we're just going to copy that okay and we're going to paste it in here so make sure because this has caught me out before that you're in the package manager console so you get this little pm um carrot or whatever you want to call it i'm just going to take out the version specification because it will derive the best version for it so hit enter and it will go away and install that for us so while it's doing that the other package that we want is the design package for entity framework core so just hit back and actually before we move on you can see that's installed okay so that's cool and we'll come back here and we'll have to do a little bit of typing so entity framework all one word [Applause] and then design and you can already see how bad my typing is getting goodness knows what i'm going to be like when i uh when it needs to be called entity framework dot design there we go so it's this package here microsoft dot entity framework core dot design and we want the package manager i'm just gonna copy that and likewise i'm gonna paste in here and that didn't seem to take for some reason there we go i'm just going to take out the version you can leave the version in by the way i just prefer to take it and let the package manager determine which is the best version that we need to use fantastic so that's basically our minimal it was not done by any means um but that's the kind of initial scaffolding ready to go so we'll take a little pause here and then in the next section we'll come on and we'll start building our model so we'll do that next all right so back over in our project i'm just going to kill the package manager console and yeah we're going to create our model first and then we'll move on to our db context so try and move through this as quickly as we can so the first thing i want to do on a project right click the project and we're going to add a new folder and we're going to call that models we're only going to have one model but we'll still pluralize the name of the folder anyway right click models add in your class and we'll call that to do like so and this is possibly going to be the simplest model you'll ever see in your life so taking your line and you know spookily or as if by magic visual studio is almost reading my mind and it's suggesting our first property what that might be and it's suggesting a public int of type id that's exactly what i want so i'm going to click tab to get that even more spookily it's suggesting our second and final attribute which is pretty much exactly what i want to call it which is a public string of type name or called name but i'm just going to call it to do name just to just because i want to and you'll also see we're getting this nullability warning here which is kind of something that's turned on by default and dot net six it's just a warning but if you want to get rid of it then we can just put a question mark after the string just to say that yes we can assume that this may be null at some point just to get rid of the warning we could leave it there but i do just want to optionally add this key attribute to decorate our property with key don't need to do it um entity framework is intelligent enough to use the convention over configuration and it knows that this is going to be a primary key but i like to just decorate it with the key attribute anyway but we do need to bring in the system component model data annotations namespace totally optional if you don't want to do that you don't have to but i just think it makes the code a little bit more well for me it makes it more readable fantastic so that's our model done um we're going to now do our db context so back in our project select it right click and we're going to add a new folder again and we're going to call this data this time and i'm just going to close down that cs proj file don't need to see that and then in our data folder right click gonna add i'm gonna add a new class and this is our dd context so called app dd context fantastic and the first thing we want to do is specify the base class that we want to make use of and that is just db context and we need to bring in the namespace so control period and bring in using microsoft entity framework core alright and then just a simple constructor ctor tab tab again and into here we're going to specify appdb context options or db context options sorry more correctly so db context options of type appdb context and then we just specify options and then override the base and those exactly what i want so just tab that over so that's our constructor there just allows us to provide some overrides okay and then the last thing we want to do is in our db context anyway is specify the db set and the db set is just a representation of our to-do items down into the database or sqlite database so public db set we specify the type in this case it's going to be our to-do model it's going to bring in the namespace control periods using to do api dot models and then we'll give it a name and it's already specifying the name that i want to use and just interestingly or semi interestingly this name is going to be the name of the table in our database when we migrate it which we'll do fairly soon and then we just want to specify we're going to set that to the following it knows what we want there as well so just set it to type to do and that's it really so we'll save that off so i've done our model but on our db context now like with most database platforms we need to tell our api where it can find our database so we need a connection string and then once we've done that we will register or db context for dependency injection but let me take a quick pause there we'll do our connection string and we'll register our db context in the next section so yeah we'll do that next all right so we're going to come on now and do our connection string so we're going to store that in config and i'm going to choose to store it in our app settings.development.jsonconfig file you could choose to put it in app settings json but because we're really working exclusively in development i'm going to put it in here so just after the second to last curly bracket put in a comma and we're going to specify our first attribute in our json file now i want you to name it in this exact way and it's going to be connection catalyst strings plural okay so connection strings and the reason i want you to do that is it allows us to kind of shortcut grabbing the connection string that we're going to specify next from when we register our db context in the next step but before we get there we need to specify the actual connection strings so colon and we're going to specify that object and you can call this anything you like i'm just going to call it sqlite connection okay but remember this this name here and then the actual value which is simply datasource equals and then basically whatever you want to call your database so i'm just going to call it two dot db and if you're not using sqlite before basically the database really just manifests as a file it's really simple actually so that's that's the extent of our connection string ideal for our purposes so save that off don't forget to save that and then we'll come over into our program class and the final well it's not quite the final step we want to now register our db context for dependency injection so in our program file in a program class after this first line we want to register it so we'll make use of our builder on the services collection and then there should be an ad db context option indeed there is and we just need to specify the type which in this case is app db context and it won't know where that is we do need to bring in the name space so control period to bring in relevant namespace and then we just need to do a little lambda to tell it where the connection string is and what i'm going to do actually is no i want to leave it open because i want to navigate here in a second i'll just make this a bit smaller and we'll specify our lambda expression so opt just opt firstly one specifies we want to use sqlite so use sqlite it won't know where this is so control period to bring in using microsoft entity framework core fantastic and then into that we basically just need to pass the connection string so we could hard code it and type in data source equals whatever you could actually do that to be honest with you we're going to be a little bit more sophisticated than that and we're going to pass in the config element from our file so in order to do that we are going to use our configuration object we access that through our builder so builder dot configuration and then we want to make use of get connection string method now we only can use this get connection string method because we come back over here we named this parameter in the following way if you name this something else or you just put the connection string as a higher level attribute you could not use this particular syntax that we're going to use all right in fact i'm going to take a new line just so we can see what we're doing so get connection string and into that we're going to actually pass the connection string name so double quotes come back over here and this is the name of our actual connection string that we want to use so just copy that and paste that in here like so fantastic and semicolon all right so we have done our model we have done our db context we've done our connection string and we've now registered our db context for dependency injection so we can use that within our endpoints what we're going to do next before we come on to doing our endpoints is just migrate this down and make sure everything's wired up correctly from a data perspective and then we can wrap this up and do our end points and finish off just before we move on to that section we'll do take a quick pause i do want to just do a build so you can do that in a number of ways you can come up to the build menu and build the solution or as i'm going to do ctrl shift and b so i just do ctrl shift d it should go away and build our solution and thankfully it has succeeded which is a good sign so quick pause here in the next section we will migrate all this stuff down and create our database and then we'll move on to end points but next migrations all right so let's come on and migrate our essentially our model down into our sql lite database so in order to do that i'm going to come into the view menu and i'm going to pull up our terminal and powershell for me and you can see that we're actually in the solution that we're working in so let's do an ls just to take a look at that and i want to actually move in to the project file so i'm just going to change in to todo api and we can see our project file like that so the first command i'm going to run is the command to generate our migrations and that's just dot net ef and you will need the dot net entity framework core tools installed i'll just take it for granted that you have those installed if you run this command and you get like an error saying don't know what dot net ef is i'll put a link below and you can install those tools it's pretty straightforward um i think probably with visual studio you get those tools by default it's just been such a long time since i've had to install them so yeah dotnet yes migrations add add no ass and then just the name of your migration so we'll just say initial migration and we'll hit enter now we'll do a build for us as well again just to make sure it's looking okay and this is actually quite a useful error that we're getting here but it's not an error it's a warning but before we address that over here you can see we now have a migrations folder and we in here we have our migrations which are basically just the instruction set that will be run in the next step to actually migrate and create our database but what you can see here is um we're getting a warning saying that the version of the entity framework tools that i was just talking about that i'm using are at this particular version here 6.07 um but the latest version is 6.08 so it's a good good warning to get actually so what we'll do is we'll upgrade these tools before we move on to the next step now this is totally optional um but it's just a useful thing to do and it's useful thing to kind of read its head so let's do that now and the command we want is dotnet tool and if you got an error and you didn't get an actual error this is just a warning if you wanted to install these tools and from scratch for you you would use install i'm not going to do that because i already have them installed i just need to update so dot net tool update dash dash global dot at dash ef okay and we'll run that and that should update our tool set to the latest version so you can see there it has updated it from seven to eight or six point zero seven to six point zero eight and again just to reiterate if you've got some other crazy warning about not knowing what those tools were you would just change this to install and rather than update okay again that's a little bit of a side step not mandatory but again worth covering so what we want to finalize now is to actually migrate uh run these migrations now we've created the migrations we want to now execute them and create our database so that's another command and it's simply.net ef for entity framework core tools database update okay onenose and that looks pretty good and you can kind of tell it's successful because you kind of get a whole bunch of like sql that's been executed to create the database and even more obviously with sql lite you can see here we actually have this file that's created that's basically our database so it's really really obvious that it's been successful so that's cool we've got our everything set up now all we need to do now from an api perspective is do our four end points and then we're ready to move on to the main event which is dot net maui but quick pause in the next section we will do our four api endpoints all right so back over in our application we're going to add our four api endpoints now and we'll begin with the simplest one which is really returning all the items that happen to be in our database that we've just created and migrated in the last section so we'll make use of app and then the map get command and get just relates to the http verb that we are expecting this endpoint to respond to so map get and into that we are going to specify the additional route that we expect this endpoint to reside at so i'm just going to say api forward slash and that's of course on top of our base server url so localhost colon and the port number fantastic and then we want to actually access our database using our context so we'll make this in a synchronous operation so we'll use the async keyword and then we're going to use the pencil injection to get an app db context so we'll see what do we want we want to app dv context and we'll give it a name we'll just say context and then we'll create the body of our actual endpoint here fantastic and it is pretty simple stuff so i'm just going to create a variable called items to hold all the returned items if there are any there might be none in fact initially there will be none but we'll just make that equal to uh waiting so async await need to be paired paired together as i'm sure we are and we'll await our context and we will find our to-do's collection which is basically our db set so we'll return or to do is as a list so to list and we need to use the asynchronous operator because i've chosen to wait on it okay and then simply all we want to do is just return an okay response with those items so return make use of results what type of result okay so we got 200 http and then it's already suggesting what we return which is just our items now we could of course done this on one line i just think this is a little bit clearer for me personally so we'll save that and i'm going to be really really brave and i'm going to run this now and we're going to test our api and we're not going to get anything of course because there is nothing there and but i'm going to copy this base url here okay localhost 7209 so i'm going to copy that and you can test this in any number of ways that you want you can test it in a web browser let's run that again and i'll tell you what actually happened there in fact let me stop this because this is a useful uh point at the moment when we run our api we are expecting that we launch this particular page here and it's actually going to the old url now when i kill that page it actually stops of api so that's not behavior that we want so let's let's clear that up straight away and the way you do that is by going into properties and looking at the launch settings json okay and we just want to change this a little bit and what i want to do is take out these two lines here of this particular profile so saying launch browsers are true which i think is probably fairly self-explanatory and the launch url weather forecast we want to take that out okay and we'll save that off so that means we can just run this up now it will still run as before on the same two endpoints but you don't get the browser and it's just keeping running so that's exactly what we want so again just to reiterate i'm going to copy this url here which i think was already in the clipboard but do it again and then i'm going to use insomnia just to test our endpoint so i'll bring that onto the screen here and i'm going to create a test request now you could do this in a web browser i just like insomnia because i just like it so new http request it's going to be a get let's paste in our base url and then do not forget the route to the actual endpoint so just move that off slightly pull this down and come back to our program you'll remember that we specified this so let's just copy this here as well so the full route is this okay and we should get nothing back well we get a 200 which is good and an empty array so exactly as we'd expect there's nothing there we're just getting an empty back so that's cool before we move on i just want to rename this to settings i'll just call it uh get all all to do the caps lock is on i'll take that off okay so it is fantastic now the only thing i want to just test as well is we did turn off https redirection so what i should expect is we take this out we're just using the http methodology and i do just want to pull out the http endpoint which is on 5209 so i guess the convention is for http the port begins with a 7 for ht sorry for https the port begins with a 7 and for http it's a 5. so we should get a 200 as well if https redirection was on it would redirect to the https endpoint which is not doing so that's cool that is all working as we'd expect perfect so let's just stop this and we'll do our second endpoint which is let's do our create endpoints we're going to create or use this endpoint to create a new to-do item slightly more complex but follows the same sort pattern so use the app again this time we're going to use map post okay so again the post verb is being used this time in a very similar way we're going to specify the route that we want to use so it's exactly the same as what we've already specified the difference is we're using a different verb so so a unique endpoint on that in that respect and in fact um very similar so we're going to have an async make async and we're going to require as before an app db context we'll call it context but additionally we're going to expect something to be passed in because we're going to be creating a to-do item we're going to expect a body payload specifying our to-do so that is also an input so type to do and we'll just call it to do and we need to bring in the name space for that using api models fantastic and then we'll just design the body don't forget the semicolon and again if you're not maybe fully following this stuff this is not a video on apis we're doing it quite quickly if you want uh in-depth explanation of how how all this is working check out one of my other videos fantastic so a little bit more complex but not that much more so we want to await again on our context we make use of our to-do's collection but this time we want to add async and we're just going to add the model that's been passed in in our method signature up here and that's it now we're not really doing any checking we're not doing any of that there's actually no validation at all so again it's not definitely not a production level api but again it's enough for what we want to do so we're just adding that to our context for those of you familiar with entity framework you will realize that anytime you make a change using a db context that's not enough on its own you also have to save it so we'll wait on our context again and we will do save changes async just tab to finish that very important if you don't do this then you will not actually your model sorry your to-do item will not be saved down to the database it won't be persisted you need to save changes and then like we did with our previous endpoint we just want to return back something so we'll return here's our results again this time we're going to return a created response so it should be a http 201 and we want to return a couple of things we want to return back a route to where this resource can be found so standard rest convention dictates when you create a resource in this case a to-do item you pass back the location where that resource can be found and we're also going to additionally pass back the json of that resource so that's all we're doing here so the first thing we're going to pass back is just telling this created method where you can find this resource so you'll find that api to do forward slash and then we just parameterize the id that we expect so to the id okay and you'll see how that manifests that doesn't make sense you'll see in a second when we actually pass it back what that will look like and that should be good okay so let me save this off we'll run it we'll test it assuming it's all well we'll take a quick pause but let's just make sure that is running it is working so run up fantastic and i'm going to pull insomnia onto the screen as well and you would need to use something like insomnia to do a post request you wouldn't typically be able to do that using a web browser so yeah if you want to start doing this stuff i would highly recommend insomnia uh we'll change this to a post i'll just go over here and i'm just going to copy this url because it's exactly the same the difference being the verb okay and let me just rename this i'll just say create to do to do that they've kind of annoyed me so that's all looking good and another thing we have to do is pass the what we want to create so we're going to pass over jason super mega simple we do not need to pass if we just come back to our model like with many other database platforms like sql server if you look at our model we are specifying that there's an id and also something called to do name sql lite like sql server will auto create this id for us so when we're creating one we don't actually need to pass the id all we need to pass is this over okay and i'll hopefully get the naming convention right it uses like a camel case so i will make that smaller to the name and then we will just say um finish in points [Applause] my typing is uh definitely letting me down at this point so that should be good enough let's see what that does and indeed it does so you can see there we got two one created and it's actually returned back insomnia does this sometimes it gives you these kind of messages that kind of obscure let me just stop and restart it it's a little bit annoying apologies for that let me just bring this back on it's just restarting up again yeah that's better so yeah as i was saying it's just exactly the same thing we just did there it brings back the actual object itself if you come into the headers you will see we have this thing called location and that is the location of where this particular resource can be found okay and we're not actually going to create an end point to retrieve this resource but um that's where you would find it fantastic so that's all looking really good and we'll maybe take a quick pause there let's have a glass of water and then we'll finish off our api with the delete and update endpoints we'll do that next all right we're just about to finish off our api so i'm just going to stop our api from running from the last section and i'm going to come back over to our program class so again just to recap we've done our get endpoint and we've done our post endpoint i'm just going to finish off now with our update and our delete endpoints and nothing really too controversial in here it's pretty straightforward from this point on so app map for update we're going to be using the put bulb which should be fairly obvious specify route again so api to do this time because we are updating an existing resource we actually need to navigate to that resource and therefore we need to use the id of that resource in the uri or the url whatever you want to call it and so we use the curly bracket notation and specify that we are expecting an id we'll then make the method the synchronous like we've done with all the other ones and pass over a request should i say an appdb context via dependency injection called context and we are also going to expect as part of the request an integer for the id and we're also going to expect a to-do model okay so basically we're going to request via the url the resource by specifying the id in the url but we also because we're updating it we need to pass over what we want to update in the body text so it's kind of like a combination but it's kind of like a bit like the post request we've just done but with a bit more complexity on top but not much more and um we'll just run that out take a new line and we'll do the body of our method so the first thing we actually do want to do is we want to check that we're going to we're requesting to update an existing resource we want to first check that that resource exists and if it doesn't we want to return back and go we couldn't find that resource it's good practice so we'll create a variable to hold our results so we'll call it um to do model because it is a model we're turning back and we'll use our context so wait on our context as before on our to-do is collection or to those data set and we'll use foster default async and into that lambda expression moves t goes to t and we'll see the id of our to-do if it equals the id that's been passed in then cool so we're going to get an id passed in here in the url and then we're going to use our context to retrieve something from our database that has that same id an image do a quick check so if the to-do model if it contains something great we have something to update if not if it equals null as our equivalent to null as it's saying there then we just want to return back and we'll just say use our results again we'll return a not found response so 404 isn't it okay assuming it's not null then we have something that we want to update so again if we were um building api properly we would use auto mapper at this point to map through the new values onto the existing model we're not going to do that we're going to do manual attribute mapping property mapping which is not great but we've only got one that we actually need to map over so we will see our to-do model the to-do name equals whatever was passed in part of body text so this to-do model will contain our new to-do text we're just going to update it manually and you can imagine a you'd hundreds of parameters in your model if you had a really complex model this would be really the boris terrible way of doing it for our purposes it's fine and you would resort to something like autumn apple in the real world and again check out i've got a few videos on automaton and then finally we'll just wait on our context and we need to save changes so it's exactly like we did up here we created a new resource we had to save the changes likewise when we update we have to then save the changes to our context then we simply return on the results and you could return just an okay but i usually return not an offend that would not make sense ain't no content so no content is a 204 success response but 204 and we don't pass anything back we're just saying yep it's updated cool save that off and then we'll move on to our delete and our delete is actually we're going to reuse a lot of the code from up here but let's just get it knocked out so app map delete so we're using the delete valve this time and i'm going to copy most of this just to save me typing and more especially to save you watch me type we're going to expect a route in exactly the same way as we had here we're going to pass in a db context we are going to pass in an id we do not need to pass in a model because we don't really need it do we we're just deleting it so all we need is the id of the resource so curly brackets round bracket semicolon take a new line and we'll finish out the body now actually in exactly the same the way that we did here we're going to do exactly this so i'm just going to copy this what we're going to do is they've given us an id of a resource that we want to delete and we're going to search to make sure that it's there if not then we return back not found okay so just exactly the same the only difference this time is that we want to delete the entry so the way that we do that is we just use our context access or to-do's collection and then we just want to remove it and the model we're going to remove is the to-do model okay so again up here i'll be search for a model if we didn't find it we return not found otherwise we actually have the full model and we just pass that into the remove command okay and you'll notice um it's not asynchronous so we don't use the await uh keyword here we just call remove but what we do have to call await is again like before on the context we do need to save changes async so any changes create update delete you always have to save it and then exactly without the same as our put model we just want to return results no content fantastic so i'm going to do a control uh shift and b to build it succeeded or run up excellent and i'm going to come back over to insomnia and i'm going to duplicate this and i'll call this update to do and i'm going to change this to put request so we're going to be passing over a body we'd expect that so again just to come back over here for our put request up here we're expecting an id in the route and we're all here and we're expecting a body as well so we need to specify an id up here of the resource we want to update so we do get all to do's actually we should get that back now we should have done that so tested that now we have one to do item with an id of one so to update that we place the id of one in here and then we just pass over the body of what we want to update so i will just say what do we want to do next uh builder my app send that over we get no content if we do get all to do's it's been updated and then finally we will just duplicate this and call it delete awesome and change the verb to delete you don't need a body okay so none nobody we just need the route we get a new content and if we return we should get an empty array fantastic so that was a very much a whistle-stop tour of creating a very very simple api in fact to be honest with you i'm trying to think this is probably pretty much the simplest yeah the simplest api you can build with uh.net there's no auto mapper there's no repository um we're using a very simple database super super simple no controllers or anything like that so but for our purposes fully functional fantastic so now we're ready to move on in the next section to building our myway app all right so we're moving on to the main event now which is to create our dotnet mavi app so it's getting rather exciting and just as a heads up i do still have the api solution running it's still there it's still operational i've just moved off screen just to create some clarity and space for us so we're going to set up our marriott now in visual studio again now just before we do that i'm just going to move the visual studio installer onto the screen here let me just make this a bit smaller so it fits in clearly and you can see i've actually got two instances of visual studio running this is the one i'm using here visual studio enterprise version 17.3 there's actually an update waiting to happen but i'm not going to do that just yet if you just take a quick look at the workloads that i have installed you will see uh that i have the net mavi workload selected and you need to have that selected in order no surprises to create.net maui apps okay so i'm not going to do anything else i'm just going to get rid of that but i just wanted to show you that you'll need to have that selected if you want to work with dotnet murray and as i said at the start you will need visual studio 17.3 at least or you can be using the preview edition but um i'm not going to be doing that today fantastic so let's pull over the new project dialogue so again i've got a totally new instance of visual studio up and running we're going to create our mobi app in that separately so create new project um i've got i've previously created my apps obviously in preparation for this video or you can find it in the drop down not the drop down and the kind of scroll selector down here somewhere i'm sure it's going to be there at some point there we go dot net my app you also get donate money for blazer i might do a video on that at some point i'm kind of intrigued by that and also the class library but we're just going to go for the straight up dot net mavic app and we'll click next for that um my location looks good there that's cool so let's give it a name i'll say um to do my client that's uh pretty good same solution name that's fine click next dotnet six long term support that's good i'll click create fantastic and here is our project all set up and on the right hand side in our solution explorer it should look very very familiar to you i've gone through probably more length than i needed to the the anatomy of a.net maui project so this should all look pretty familiar to you and we'll be working with this stuff to a lesser or greater extent as we move through the rest of today's video so what we'll do is we will run this up in windows so you can see here in visual studio you get these options to run uh on different and i can keep calling them endpoints probably shouldn't do that on different systems different platforms platforms really is probably the best way to describe them so let's run on windows just to make sure everything's running okay and then we'll run an android as well and as i say if you want to build uh or really run i suppose you can build apps on windows but if you really want to test them on an android an ios device or a mac you do actually need access to a mac to do that all right now it's started on my other screen so let me just pull that over onto the screen for you and you can see that it looks like so you have the.net robot i don't know what his name is and should probably find out what his name is and um you just click the button and it just increments the number of times clicked so very very simple just uh kind of hello it is it's a hello world application so we'll get rid of that and to run it on android um just to set it up go into tools uh go into android android device manager now i have found and again i just got a pop-up on screen saying do you want to run this yes um when i ran this the first time i actually said i needed to move windows into developer mode or enable developer settings the way you do that before we carry on come on here certainly on windows settings again i do apologize it keeps popping up on my other screen let me just bring this onto the screen and if you just type in developer developer settings you just need to make sure this is switched on developer mode is switched on that's what was the words i was trying to find and if this is off it's usually off by default you will have i think you might have problems running this android device manager and you can see here i already have an android device set up if you wanted to set up your own one click create new device and then you just select the profile down here um i selected a pixel 3a again i just selected it from the microsoft learning path i think it was a pixel 3a store i think everything was the same there i think that's correct in fact we can maybe look let's have a look at this card let's have a look at why did actually create yes so these are the settings i used if you want to use the same ones maybe that's the best way to go about it so pixel 3a store the has a name and then the the actual os which in this case is android 11 api 30. and i did bother selecting google play store so that's what i've got if you want to follow along exactly as i have then you can use that you can um once you've set that up in your drop down you can then go into the down arrow here find android emulators and select the device that you've just configured and then you can click run like we did with windows what i tend to do because there's a bit of startup time required when you fire up the emulator what i tend to do is i tend to start it in the device manager so it's just running all the time it's just there parked off as an app in the screen and then when you click run from here it just finds the running instance so you're not doing that up and down all the time because it can sometimes take a bit of a while to boot up and so i have my instance up and running here and then if we click uh within visual studio let me just bring that back onto screen you should see that exact same app executing in my way and you'll probably see down here that it's think about compiling i think that building and then you'll see that it's looking for the emulator and it should hopefully find it without any problems and it will all spring to life and you can see that it's from the emulator device that we've specified and then we should see some activity in here now once it's done this once it tends to be a lot quicker the first time it's a little bit slow um but once you've done it once it's actually pretty snappy and you can see there we've got our.net app running and it should load in a second and we have the exact same hello world app okay so it's pretty cool and you know the android emulator works exactly as an android phone if you have one of those um otherwise you can just stop that and that will stop it from executing the actual android device will stay running because i started it from the android emulator what's it called android device manager yeah so it's still running so i'll move that off to the side of the screen and as we move in and out of an application um we'll use either windows or android i like to test on both because i've actually found um some interesting results sometimes depending on which one you're using so we'll start them on both instances fantastic all right so that's really our initial setup no there wasn't really a lot involved um ready to go and we'll take a quick pause there and then we'll actually come on to start coding in the next section so we'll do that next all right so we're coming on now to actually starting our.net maui app build which is rather exciting and just before we do that i did just want to reference our my application architecture so we've scaffolded up our app we have these three things already we will make reference to them or we will do some work in some of them a bit later but not right now we have our main page xaml file and but we don't yet have our model so kind of fundamental to the app the whole application so the next thing the first thing we're going to do is create our to-do model and then we'll move on in the next section to do a data service but we'll that that's let's not get ahead of ourselves and let's do that a bit later so back over in our project um right click the project and click add new folder and i'm gonna create a folder called models and then right click models add new item and it's a class by default which is what we want so to do dot cs and we'll add that in i will just change this from internal to public and then we're going to create the exact same two properties that we had in our to-do model in our api but we're going to construct it in a slightly more involved way because we want to actually be able to trigger event changes on these properties which you'll see how that will manifest a bit later so in order to do that first thing actually we want to do is to specify the use of a particular interface which is i notify capitalize that property [Applause] changed and we'll need to bring in the namespace for that system component model cool and then it's still complaining because we're not actually implementing that interface so ctrl p again to implement the interface and that just provides this event here we don't really need to do too much more with that so we'll move that down and we're going to work with the same two properties but we want to kind of work with these events so what we're going to do is we're going to create some internal fields that will represent the the id and the to-do name so specify an integer as it's a kind of an internal variable underscore and we'll call it id and we'll also do one for the name the to-do name so string underscore to do and we'll actually keep a lowercase to do a fantastic okay and then we'll actually specify the properties so prop tab int and we'll call this one id take a your line taking your line taking your line clicking your line and forget we're just going to make that equal to underscore id like so if i can find the semicolon key that would be fantastic and then for set get rid of that in some curly brackets and this is where we want to kind of just say if underscore id is equivalent to the value that we're trying to set it to just return otherwise id equals value it's doing a bit of code completion for us what's lovely and we want to then kind of raise an event so property changed invoke it and i think we can pretty much just take the suggestions as is but i'm just going to change this to id and we will change it slightly by saying across on the right place name of id okay and i think that's good all right so hopefully that made sense so we're just creating our public property which is called id and then you just get it in the regular way uh the set operation is just going to invoke a changed event if it if the value changes which hopefully that makes kind of sense we're going to do exactly the same thing for our a to do name property so prop string this time not sting not the lead singer of the police uh and we'll call it to do name and in exactly the same way we'll just simplify or get so make that equal to underscore to do name i think somebody's moved that semicolon key uh they've moved it they've moved it that's why i'm continually typing the l character so uh and then set will do exactly the same thing so we'll say if to the equivalent to the value we want to set it to then we'll just return nothing to see here otherwise to the name make it equal to the value and we'll just raise an event so property changed invoke and we'll see this new property change event args that's what we want the evolve and then the name of our property to do name and finally a semicolon and we need to put an equivalency operator and they're not and equals and i think that's looking pretty good so we'll save that off and i'm going to do a control shift and d just to build it just to make sure i've not introduced any crazy errors there we go succeeded which is um not unexpected but most most welcome all right so it was a little bit longer than i actually thought it was going to take because we've got slightly more complexity in our properties there but um yeah nonetheless we're done with this so in the next section we are going to move on to building our data service and which is going to be responsible for calling our api so kind of almost independent of memory it's not really a memory concept but nonetheless absolutely necessary for our my app to work in consumer api so we'll do that next all right so we're going to move on now and we're going to start creating our data service and the data service is not actually on my concept but it's something we can build independently of doing anything else so i thought we'd get out of the way now basically but it's obviously super critical to our application functioning so we're going to create a new folder for that so select the project don't want the cs proj file and right click that we're going to add a new folder first and i'm just going to call that data services even though we're only going to have one and inside data services folder we're going to use the standard interface concrete class implementation and then use dependency injection in order to make use of well that interface but fundamentally the concrete class we're using dependency injection to do that we're going to go through everything step by step here but i'm going to focus on how dependency injection works if you are a bit fuzzy on that i do actually have a free course on my other website lesjackson.net totally free you have to go there and register for the.net developer toolkit course and that is a free module so you just need to register and you can absolutely go for your life and learn about dependency injection in depth okay so if you're a bit fuzzy on the eye check that out i've got lots of other things over there as well so take a look but back to the order of the day the work at hand that is our data service so the first thing we're going to do is create our interface so right click add and we're going to do a new item and we can probably select an interface indeed we can and i'm going to name this capital i or interfaces should really begin with an eyes good practice and i'm just going to call it rest data service so this is our interface it's just specifying the method signatures that are available via this interface should you choose to use it and subsequently implement it so i'm going to make it a public interface and then it's pretty simple to be honest with you we're just going to specify four method signatures one for reading data one for creating one for deleting and one for updating so we're going to make them all asynchronous so we'll specify the return type as a task and then in the case of the first method signature which is returning all our to-do items from the api it's actually going to be a list type which in turn is a list of to-do items okay and we need to bring in the namespace for to-do so ctrl period using to do my client models which is exactly what we want and i'm just going to call this get all to do's look at that look at that my goodness i think somebody's messing around my keyboarding or they're moving the keys around um all to do and we'll say async and i always forget to do this if you make uh your own asynchronous methods you really should name them whatever you want to name it followed by the async word it doesn't have any functional impact but it's just again more readable to know that it is an asynchronous method cool um we've got a few more to do um so task this time we're just adding a to-do async as well and this time we would pass in a to-do object and it's kind of kind of spooky that it knew that i wanted to do that i kind of like it and i kind of i'm kind of scared of it at the same time so um so it's already suggesting a delete which is kind of spooky i'm going to tab over but all we're going to pass in this time is an of i id and then finally uh not that intelligence pretty good not quite quite there we're going to do an update as well update to async and again we're going to pass over a model a to-do model for that as well and we'll run that off with a semicolon so that's an interface to find and we'll save that off i think that's looking pretty good i just want to make sure that auto generated one delete to do yeah that's correct um that looks pretty good so and we'll take a quick pause here just to kind of break up a bit and in the next section we're going to start building out the actual concrete implementation class for our data service so we'll do that next all right so when i'm moving on to doing our implementation of our interface so right click data services add new class and we're going to give it exactly the same name it's except this time it won't begin with an eye it's just going to be called rest data service perfecto and we'll make it public as well and it's going to implement our i rest data service and we'll complain because we've not actually implemented it so control periods implement the interface and we'll just put in a load of well not a load four placeholder methods that relate to our method signatures in the interface all right now before we come on to start implementing those i do want to kind of start creating our constructor because we're going to ultimately use constructor dependency injection to allow this whole thing to work so c2r for constructor tab tab and we're going to say underscore http client equals new http client all right don't need that extra bracket and there's obviously erroring out here so we do need to actually create this as well so we'll just say private read-only http client called underscore client and in fact actually we get rid of that if you actually just when that errors out you can place your customer under control period and just do generate read only field and you can get it in exactly the same way with much less typing so we'll do it that way this method of dependency injection we're going to register it in a bit in our mummy program class and we're going to register as what we call a singleton lifetime cool and i think that's really the way microsoft recommend you do this if you're choosing to do it in this way i've seen a few questions around the interweb about http client factory so park that for the moment i'm going to come back and revisit that a bit later but for now we're creating it this way and we're going to register this as a singleton okay and again if you're going what is that um maybe check out my dependency injection module which is free in the dot net developer toolkit i'm not going to say that anymore i'm not going to promote it anymore i've said it enough so you can go and check that out lesjackson.net check it out all right cool so we have our http client which we're obviously going to use to contact our api which is good i want to set up a few more private fields really that we're going to use throughout the rest of our methods now the first thing i want to actually specify is something called the base address and what that will relate to is the the address actually bring on uh bring over around insomnia the base address is really just this part here the server name up to and including the port number okay that's the base address i want to configure that now uh this is probably going to be a bit of a digression in a development environment as we are running now our endpoints are running on local host okay and that's cool that's fine no reason why that shouldn't be cool or fine and when we run our instance of our murray app in the windows configuration happy days nothing to see here move along if we try and access localhost from our android device it does not like that it will not allow that okay and i'll actually put a link to some microsoft documentation it talks a bit more detail about this but i want to just go through it here we can't use the term localhost we are given a kind of proxy address that you can use to access local host devices from an android device it's an ip address it's something like 10.00 10.02.2 something like that i'll check the code as we go through it and we use that instead that's point number one so when we are specifying this base address uh field we want to kind of allow a distinction a platform distinction to be made between are we using windows or are we using android and in fact really all we want to determine is are we using android if so use this special uh ip address 10 or 10 range ip address otherwise just use localhost the other point again specific to android is if you want to use https there's a lot more configuration required only in uh local development environments and i've decided maybe redundantly because i'm talking at length about it now and i want to explain it to you that i don't want to bother doing that and again a link to a microsoft article that will show you the config that you need to go through in order to enable https for android in a local development environment we're not going to do that what we are going to do though is we're going to use if we're using android we're going to say use the special ip address and we're just going to use http that still requires a bit of config which we're going to do so this base address that we're going to specify i will get to my point eventually when we are using anything other than android we're only using android or windows in today's video if we're using anything other than android so basically windows https localhost fine don't couldn't care if we are using android there is a special condition we want to use the ip address and we only want to use the http schema now again most usually i would never ever recommend using http but for this video it's not really the point i don't feel any way and it's a development environment so it's fine in production scenarios you don't actually have these issues you don't have the issues about not being able to access localhost and you don't have the access the issues with https either so it's actually a lot easier it's just we encounter this in development whoa okay so hopefully that was clear um so we're going to specify a little bit of logic around our base address we'll do a couple other um private fields and then we'll maybe take a quick pause and move on to actually implementing the rest of our data service all right cool so i wanted to explain that ahead of time hopefully i've done a good enough job of it so with that in mind we're going to make use of something called uh device info and we're going to say what type of platform is it so if it's equivalent to device platform and you've got an enumeration here of all the different things it can be running on we're going to say if it's on android then the base address is going to be http colon forward slash forward slash and i'm going to make sure i get this correct because when i was preparing this course i actually typed this i can't believe it i typed this address in wrong and i couldn't figure out why it wasn't working anyway um so please please please if actually if anything's going to go wrong if anything's not going to to work with this whole thing it's going to be this right so be really careful that you type in correctly so it's 10.0.2.2 and i think i typed in 10.0.02 or something crazy stupid like that and then the port number so i can't remember what the port number is we bring it over here so we're actually calling our http instance here so it's five two zero nine okay just make sure that's correct yep five two zero nine perfect five two zero nine so if we're using android that is our base address otherwise let me just unpin this otherwise we are going to just use https closed captioning not schema so available just make sure that's correct that is correct so 729 perfect 7209. all right that looks pretty good to me so that's our base address we're doing a little bit of logic to determine what is fantastic um clinton claiming that we don't have a base address so control period and we'll do a read-only field for that as well that would only stream for base address and then going to specify a url and url's just building up building up what we actually want to construct and pass with our request so url equals we'll use string interpolation so dollar sign double quotes and we'll make use of our base address fantastic and we'll just say forward slash api okay so basically again i know you know this now that's basically constructing us up to here and then really when we come to making our calls the theory is that you may have more than just the to-do endpoint you might have other things as well but the api section is kind of consistent or should be certainly in our setup all right hopefully that made sense uh so such api let's just finish that off that's cool url is complaining so we'll do exactly the same thing there so control period generate a read only field good and then the last thing we want to do is we want to set up some json serialization options now um we're going to be using the microsoft json serializer on d serializer which is systemtext.json um and again i ran into an issue with using but it's not an issue using that but i use the newtonsoft json to begin with and that kind of worked out the box no issues and when i was pivoted because i want to use the microsoft variant which is system text json and i didn't supply this stuff the serializer options i had a few issues so we're going to specify some explicit serializer options actually i'm going to break a promise i made to you earlier if you want to learn more about json i have a json module in the net developer toolkit you do have to have to pay for that one though but check it out if you're interested but again we're going through all fully step by step here so we're going to call this json serializer options json serializer options perfect equals new json ceo hi allies uh options i need to bring in the namespace control period so system text json so it's the microsoft deserializing stuff let me call on there let's just make this uh generate a read only field so private read read-only json serializer that's looking good and then the two things we want to see actually the one thing we want to set is just the property name and policy so property naming policy and we'll just say json naming policy is camel case and this i hadn't said that explicitly here i was causing all sorts of problems all right so that's our constructor done and we've not implemented our methods yet so that was a bit longer than i had anticipated um let me take a quick policy and we'll start then implementing on actual uh actual endpoints just before we do that let's just do a quick build just to make sure i'm not introduced any crazy errors and then quick pause and we'll move on to doing our other methods excellent that looks okay cool so uh we'll take a quick pause here and then we'll come on and start implementing the rest of our methods all right so back over in our data service class we've just completed our constructor and what i want to do now is move through and complete the rest of these methods so the first one i want to tackle is the one where we get or attempt to get all our to-do items from the api so get rid of that i'll make it a sync and i'm now going to create a list that's going to hold all our to all our to-do items and simply by typing lis visual studio kind of knows exactly what i want to do which is rather spooky so i want a list of to do items and it's created a new list for me it's pretty cool now this next line i lied to you unintentionally of course when i said the data service is completely divorced of any memory concepts we're going to actually make use of a merry concept in here which is to test connectivity device connectivity to the internet because obviously we're going to reach out over the internet and get our api called make our api call and get our to-do's so there is a memory concept here we're going to make use of connectivity and current and network access and if that doesn't equal network access internet then there's no point in making an api call so we're just going to return so under console rightly which might do a debug writeline since we're using um visual studio bring in the namespace for that debug rightline system diagnostics whiteline and we'll just say something along the lines of no internet access okay and we'll just return our to those our empty our empty list so we'll just get an empty response from that perfect assuming we do have internet access we'll put this in a try catch block because it can still go wrong we will say http response message there we go call it response and we will say await on our http client that was created in our constructor get async and wow it's pretty clever specifying that we want the url it's almost right you know it's almost right we don't just want the url though so double brackets curly brackets we'll put the url inside of that and we will specify to do pretty good so again just to kind of reiterate our url is our base address plus forward slash api and our request now our get async request is to the full endpoint that we want which is just to remind you this one here okay perfect now if you're watching any of my other videos this kind of stuff should be relatively familiar my video on blazer clients basically does exactly the same thing so this is all just kind of vanilla http request type stuff so we'll say if response there is success code then we know we've had a 200 response of some description then we'll do a bit of json d serialization but otherwise we'll just say obviously there's some kind of issue and we'll just do a debug writeline and yeah just again you know you don't need to put this debug stuff in i'm putting it in because i'm typing this live and i might make a mistake so it's just useful to help me debugging um as and when we may encounter errors so just say non-http 2xx response [Applause] okay that should be good enough and we'll come back don't worry we'll come back to this uh section here i just want to put in the catch block so otherwise there's been some kind of catastrophic exception so we'll catch the exception and call it ex and we'll just do a debug write line again and we'll just say we'll use string interpolation because i do want to display the exception to the screen and we'll just say whoops except exception and we'll just put the message of the exception in here okay and either way we'll return our to-do's okay so again if we're not properly d serialized we're gonna populate it in here if we but once we deserialize otherwise if there was an exception we're just gonna end up returning back an empty list so come back in here this has been successful so we want to get the content of our response we'll make that a string we'll call it content and we'll await on our response and we'll use content and we'll do a read string async perfect and then finally our to-do's equals json serializer dc realize and what do we want to do serialize too we're going to do serialize to a list of to-do's and what is what are we wanting to dcelis from well content and very importantly i didn't originally use this or json serializer options which is really just specifying the use of camel case all right so that's looking pretty good um that's getting all our to-do's i think that should have made sense to pretty much everybody and let's do a quick build and then we'll pause and we'll move on to our other uh other methods so save this first quick build just to check that's okay and then we'll move on yep looking pretty good so all green lights clean good to go we'll move on next section to do the rest of our data service methods we'll see you then all right so we're going to just keep going through and building out our data service so it's you know a little bit repetitive possibly a little bit boring i did think about maybe doing it in stages and you know progressing with other parts of the build and then coming back to this and finishing off but i actually thought it would be better just to get it completely out of the way so we can kind of put it to bed so with that being said let's get going so the next one i'm going to do is the add to do async method and as you can see here it accepts a to-do object and whether we're going to call the api we've created with that object and it will get added to our database fundamentally so let's get rid of that we're going to do exactly the same thing here um not exactly the same thing i'm going to create a list but we're going to do this check for connectivity and that's still a value a valid uh thing we want to do here and we're just going to return i'm not going to tell them to do is we'll just return and we'll just return back and it's complaining because we need to make this async as well that error should go fantastic so we'll put the rest of it into a try catch block we will do the catch block first just because it's slightly more generic so we'll just catch an exception we'll call it ex and i was maybe going to copy from here so i want to try and save as much typing as i can this one here and i'll just copy that and we'll paste that into our exception here and actually what we'll just do is we'll just we'll just put a return in here as well just to rip that out and then all we really need to do is just populate our try block so the first thing i really want to do inside our dry block is serialize the object that we have passed in so we're going to create a string we'll call it json to do and we'll make that equal equal to json serializer called the serialize method what type do we want to serialize to well that's our to-do class and what is the source of our what's the source that we want to see realize it's this to-do object up here and then we also want to pass in our serializer options that we created earlier on we want to make sure as well we then want to create what's called string content as we're going to pass this ultimately over with our request our post request so we're going to post stuff to our api so string content and we'll call that content and we'll make that equal to new string content first thing we want to pass in is our json serialized json object so json to do specify our encoding and i think we'll probably need to bring in oh we don't but we might need to bring in the name space there we don't so we want utf-8 and then we just want to specify as it says the media type which is application json and we use this string content with our post request before we do that though we need a http response message call that response and we'll make that equal to a weight use our http client we'll do a post async what we're posting to so we want to post to a particular url so i might just come down here and copy this because it's exactly the same end point that's not the same endpoint but it's the same url url different method though different verbs we're posting rather than getting but it is the same string basically or the same yeah the same url and then we also just want to pass that content that we've just created over and then it starts to look a bit similar to be honest with you we check whether the response is a success status code and if it is yeah let's just rewrite let's write out some sort of success debug writeline outline and we'll just say successfully created to do i think it's useful just to do this debug stuff because just in case there's any errors that i've introduced i just want to have this stuff already in here um otherwise we'll just uh write out something else like uh the non-200 response so just copy that and paste that in here like that and then that says done really so really you know if it's successful um we will obviously have an item added be our api to our database and we return anyway otherwise yeah we'll just capture the exception or respond with this and we'll write out this error like error message here so i'm going to save that i'm going to take a quick pause just to break up a little bit and then we're going to come on and we might see if we can do both our update and our delete in the same section but yeah quick pause here for now and we'll come back and finish off all right so let's come on let's do a delete endpoint next or not end point let's do our delete method next so get rid of that and like with our other methods we want to kind of do a connectivity check first so i am just going to uh i copy it from a copy from here doesn't really make any difference it's exactly the same thing isn't it so uh paste that in here you've seen it before and again it's error yes it is erroring um because we need to make this async and that should get into that fantastic now as you can see here our delete async method that just takes an id of the resource we want to delete so it's actually a little bit simpler than i add or add endpoint so we'll put it in a try block anyway try catch block anyhow and we'll do the catch first trap the exception and we'll just write that out to the screen so i'm just going to copy this as well there's actually a lot of repetition here you can see and looking at the microsoft example at which i base this around to some extent um they actually combined not the delete method but they did combine the ad and the update and you'll probably see why they did that um we could do that but i actually wanted to deliberately keep them separate um there is a lot of repetition though so there probably is a way we could kind of de-duplicate some of this because it's very very similar but i think this is probably an easier way to do it in terms of explaining what's going on so we're going to stick with this approach for now might finesse it a bit later in another iteration um but that's that's just catching the exception and then the try block is a bit more simple than the add one so we just want a http response message now we'll just call that response and we'll just await our http client oh i don't know what that was http client and this time we want to delete async which i don't think really needs too much further explanation i will copy this however it's not fully correct we do need to add on the resource id that we want to delete so that gives us so much but not everything so curly brackets and we will just put in the id that was passed through with this method like this okay and that should give us the full route to our delete endpoint in the api and then very very similar what i might do is just copy this it's really just i mean technically you could say we don't want to do this or you could do something a bit more intelligent in here you know if it's not not successful status code but i'm just going to do this for now just to get us up and running quickly so it's basically doing exactly the same thing okay and that's looking good so we'll save that off i'm just going to do a build i'm not done that robot let's just build it just to make sure it's um okay okay that's looking good fantastic and then the last one we want to do is our update now i'm pretty i'm going to basically copy everything inside our ad to do async because there's only a few very very minor differences between the two and i can understand why yeah microsoft wrapped it into the one method i can totally understand why they did that but again i want to keep it separate we're still passing over the main object we do need to make this async as well just to get rid of that error we still want to do this we still want to serialize the object that's been passed through because we want to update that that's all cool we still want to create a string content object like we did here as well and we still want to have a response message like we had here but the only difference and i'm sure you can probably understand what it is we're literally rather than posting we are putting async and then obviously with that and you'll remember if i just bring insomnia back onto the screen case you have some slight amnesia um our put endpoint did require that we passed in a resource id so we do need to do that of course here as well so forward slash curly brackets and we'll just use the to do object and we'll get the id from that and we'll use that as the resource id which should obviously match and we'll save that off fantastic so we'll do a quick build but i think that's going to be pretty guaranteed to be okay cool and yeah that's built successfully so that's great so the only other thing i want to do with regards to our data service is register it for dependency injection so i want to come over to our mummy program class and just before we return the build i want to just come in after here i want to make use of a builder object which is a services collection dot services i want to add singleton and again if you don't know what singletons are versus transient versus sculpt then yeah check out my course on jackson.net and it's free you can learn all about that over there but fundamentally all we want to do is just register in our dependency injection container we want to see if any part of our application asks for a rest data service interface then we want to give them for implementation and we've already done our implementation and we want to give them this rest data service implementation and the idea with you know dependency injection just let me bring these namespaces in control periods to bring those in the idea with dependency injection is that you consume this really and the dependency injection system will then give you whatever you specify here so as long as your concrete class is implementing this interface these interface methods and you can basically swap this out just here and you don't have to swap it out or do any other changes anywhere else in your app that's fundamentally one of the main benefits of dependency injection so that's just saying okay cool we're registering that and it can be used as i said elsewhere um we are going to revisit this towards the end of the project and use a http client factory instead but we're going to go with this method this is this works perfectly fine and you can use this for this application so um we'll maybe take a quick pause there and then what we're going to move on to next where data service is basically done what we're going to move on to next it's kind of related to our data service is doing that extra android configuration that will allow us to use localhost um development type environments we'll pause here for now and we'll come back and do that next all right so we're going to come on and do our android specific configuration for local development environments and i'll actually just save this uh my program class first before we even go any further and just to again refresh from emul that wasn't that long ago we had this whole big well i had this conversation with you around making a determination whether it was android and if it is then we have to use this particular ip address and we also in this case i'm choosing that we're just going to use the http scheme rather than https and that's just for reasons really linked to android's security layer and nonetheless that's still not enough at this point to allow us to call http endpoints from android we do need to add a little bit additional config now i will link to this below i don't recommend you take a read at this let me just um resize it a little bit so this is you know the some of the microsoft documentation on dotnet maui i'm just looking at this connecting to local web services page and actually goes through everything you really need to know about configuring for both ios because there are similar configuration options with ios as well as android for very understandable reasons um and it goes through them here but again we're just working with android today and what we're going to look at and the instructions i'm basically following are this here android network security configuration and there's two things we need to do and it goes through them here so the first thing we need to do is add something called network security config to this path here in our project and we just basically copy this over here and you can see there's the the ip address being specified and then the second thing is we just need to update the android manifest xml file uh with some additional config and we'll do that as well all right so let's get cracking with that and again yeah if you wanted to run local web services or https you can do that and the thing i'm kind of avoiding doing is adding this stuff here which you can see it gets a bit complicated there's a bit more work set up and i just felt wasn't really worth the effort for this video if you're really interested in i can make another video and do that as well i just felt it was a little bit a little bit dry and you can read all about it here anyway so link to this documentation below yeah i do check that out so back over in our project the first thing we're going to do is add that network security config xml file and you can locate it under platforms android let me just make this a little bit bigger resources and xml now the xml folder does not exist so just right click resources add a new folder and we'll call it xml or lowercase and then in here we'll add a new xml file so right click add new item and we can probably specify an xml class so data i think it's under yeah xml file and we need to give it a very specific name so make sure you type this name incorrectly all lower case network underscore security straight away i can see i spelled the wrong sec update xml that's looking good to me and so we'll add that in and then i'm just going to copy it in from the microsoft article in fact because that's just exactly what we need so it's this one here this batch of xml and you can if you wanted you know you can you could add in for the sub domains but really all we're doing here is saying that this domain here 10.022 allows clear clear text traffic which is http basically so uh we'll copy that and we'll just paste that in here we need that but that's already included in that file so that looks pretty good we just saved that off and then the final er but it's not the final final thing but in terms of configuring android for http we need to then just update the android manifest file so let's double click that and you just need to add a new config series of attributes in here so i'm just going to do it directly after application and before the rest of the existing stuff again i'm just going to copy it directly from the microsoft article so it's got it here and it's just basically this this string here that we want and we'll just paste that in into here like so that looks pretty good to me and all it's doing is actually just referencing that file we have just basically created so just make sure that matches network security and just double checking the name again it matches up because as i say if you're going to get any errors or issues it's going to be around this networking space it's not going to be with my way as such it's going to be around networking permissions and things like that that's why i've found anyway that's the thing that had me scratching my head a few times anyway that's cool i think that's everything done there that we need to do so yeah getting a bit more exciting now we'll do a quick architecture check to see where we're at in the next section and then we'll move on to looking at our main page and repurposing that for our to-do app but we'll do that next all right so we're coming on to arguably the most exciting stuff now because we're really talking about maui features and functionality so let's just bring up all our objects here on the screen and just do a bit of a sense check of where we've got to so we've clearly created our model which we've done and we don't need to touch that again we've created our data service which we don't really need to touch again assuming we've built it correctly we might need to revisit it in case i introduced any errors but should be fine and we've got our three kind of core classes over here which we will start to work with a little bit now in fact but what i really want to move on to now is to work with this first page here our main page xaml and the code behind and at the moment this is just rendering the very simple click application that i showed you and we want to basically destroy that get rid of that but keep retain this page in place and we're just going to repurpose it for our own purposes um so the first thing we're going to do um one of the main things we're going to do is we're going to allow our main page cs files mlcs file to make use of our data service to retrieve all of our to-do elements and in order to do that we're going to inject this data service in through the constructor of this page so it has that available now in order for that to happen we also actually have to register this main page class itself for dependency injection so that's probably the first thing we'll do next and then we'll begin with the rest of the methods in that code behind page before moving on to the kind of arguably the kind of visual ui stuff which we will do in the xaml file all right so hopefully that kind of made sense but um let's get started and um yeah first thing we'll do is we'll register this page for dependency injection and then we'll inject a data service in there so back over in our app i'm just going to minimize that or collapse that and we'll go into the code behind for main page and this is the code that we had as part of the default app so let's get rid of that so there's a an integer for counter and there's a counter click method which we just don't need either so let's get rid of that we'll keep our constructor we want that now just one thing to call out you can see this is called main page as a class but it's inheriting from this content page which i was talking a little bit about earlier okay so a page that displays a single view blah blah blah won't go over that again uh we're going to keep this as practical as possible so the first thing we want to do before we come back and work in here is come back to our main oh sorry our murray program class and we want to register that page for dependency injection so builder services is also a singleton and there's no interface we just want to register the class itself which is main page okay so you can see here this this method here we used an interface and a concrete class this one we're just registering the the class itself and you can obviously do that and that's why i'm doing it um but you want to understand the differences of why you would do those things again the course i have on risejackson.net will take you through that okay so that's cool um we can come back to this now so in order to use that we will inject through the constructor and instance of i rest data service and we'll just call it data service okay and we'll bring in the name space for that control period now a very standard pattern for constructor dependency injection.net is to obviously get the instance of iris data service injected through here but we want to sign it to a private read-only instance of the same name but we just started with an underscore so we'll say underscore data service equals data service and we do of course need to create this so control period and we'll create a read-only instance of that excellent so that's our constructor done so as i said what we want to do is when this page starts we want it to go away and grab a list of to-do's we'll use the data service to do it and we'll use the method on that get all uh to do's the method that we can use to do that is a method called on appearing and as the name would suggest it files when the page is appearing and there's also a disappearing one as well so maybe make use of that is to introduce it so it's protected we want to override it that's async first of all override void and on appealing then you'll say it will file when the page starts to appear make use of the base on appearing tab tab fantastic and then what we want to do is we don't have this yet but we are going to make use of our collect a collection view and talked a bit about views earlier on and we do need to introduce this via our xaml in the other part of our page the main page xaml but for now we'll assume it's there so collection view specify the item source and we'll make that equal to a waiting on our data service and we want to get all to those async doesn't require anything to get past him and this is trying to be a bit too helpful for us but it's actually a small collection view and as you can see here it's basically saying does not exist and that's true we don't it does not exist yet we will build it into our main page xaml though so the moment this is just kind of erroring out for the moment that's okay we'll fix it up in the next section and the only other thing i want to do here is create two placeholder event handlers because on this page we're going to list all of our to-do items but we also want the ability for a user to click a button and add a new add a new to-do item or select one of the existing items and trigger an update or you know an edit page so that's two event handlers we need to register here kind of on clicked um on the existing items and also one for creating a new item so let's get on with that so the first one i'm going to do is when we want to add a new item to our collection so i'm going to make the event handle async as they will must usually always be boyd doesn't really return anything and then just give it the name on add to the clicked and really pay like i'm attempting to here pay really close attention to the naming of these and most importantly what i'm going to do next the event args that you use before we go into event logs though this event handler takes two parameters an object we'll call sender and then the event args so for this one we are just using kin of the vanilla generic event args and assign that to e and i think i'm having trouble with my brackets because i'm used to using visual studio code and it doesn't do quite as much for you as visual studio so yeah it's maybe too helpful visual studio sometimes anyway i just want to wire this up we're not really going to do anything in this because fundamentally when you click on this what we expect to happen is to navigate to our new page the manage page and we put in text and things like that we don't have that yet so we can't really do that but what i do want to do is just put a debug right line in there just to enable us to test it so do that very quickly so debug i need to bring in a namespace for that whiteline and i'll just say add button clicked cool i'm going to do one for when we you know again we're on our main page and we have a list of items we want to select one of those items and that will navigate us to the same page but it will populate the details of that existing to-do item so that's the event we want to then handle we want to write here now again be very careful because i ran into this trap and i anyway we'll see when i come to i've used the wrong event handler i use the same event handler that i'm using in this method here and it requires a slightly different one and that caused me all sorts of problems so anyway just be very careful with what you type in here so we're going to call this unselection changed the first argument is going to be the same it's going to be an object we'll call it sender but where i tripped up was i just use the bent axial it's not that you need to use selection changed event args and just make sure that spell it correctly as well that would definitely help and we just pass that into e all right perfect i'm just going to do the same thing so i'm just i'm happy to copy this we'll change the text though and um yeah in the next section we will attempt to use at least this one here the add one delivered a bit more work to do to get this one tested as we need to pull through the the items in order to test that but um anyway good enough for now so we'll just say um item changed clicked perfect let me put an exclamation mark in because we're so excited about it working all right so maybe leave that there for now and in the next section we're going to come back and focus on our app shell we're going to focus on our main page xaml which is the user interface uh stuff for our main page so we'll um take a quick pause and we'll come back and we'll start working with that next so we're focusing now on main page zones let's just take a quick look at that and you can see this is just the markup that presents the default page you get out the box with the scaffolded app and you can see there's a button here that requires an on counter clicked event handler which no longer exists in the main page the code behind page the cs page that's no longer there so this will actually cause an error to be thrown if we try and run the app now in the same way coming back over here this collection view does not yet exist in main page so it's about a chicken in an egg scenario we've got two sides of our page that require certain things to be there and neither of them are there and this will cause arrows to be thrown now in the case of this i don't want to delete this i'm just going to comment that out for now because i don't want to have to retype that in again but in the case of main page xaml i want to just take out pretty much everything that's there so if you just select everything from the scroll view just take that right down and delete that out and that should just leave you with the content page tags so this is basically an empty page now okay you need this stuff at the top you need the schemas and things like that so let's just save that off let's just save that off and let's run up the app and we will expect it to run in our my uh i don't know in our android device manager instance here so let's just click start and that's run up and our home page now our main page is just blank okay there's nothing on it which is exactly what we expect exactly what we want so i want to use this hot reload functionality when it comes to editing xaml and indeed code i feel it works really well with the xaml stuff though and you will see your design evolving as you type in your code which i think is a really nice feature and that's actually the way microsoft recommends you do your design there are no more visual designers that you maybe got in previous iterations where you can drag and drop controls onto a surface you don't get that right now they may introduce at some point but for now the recommended approach is to do to use hot reload so let's move back over to our main page zamo and we'll start building this out and you should start to see changes reflected in our android instance here so the first thing i want to add is what's called a toolbar i'm sure you can imagine what that is our toolbar item so make use of content page and i want to select toolbar items and again it's very well it is essentially xml it's a variant of xml you can see those opening and closing tags and you can have them kind of nested inside each other so it's very very similar but it is essentially xml but just slightly different so want to add toolbar item toolbar item set the text for it and this is going to be for our add button effectively and in this instance for android it will appear at the top right hand corner here will be a little bit of text you can click to add a new item so the text for that is just going to be add to the and then we want to specify the clicked event handler and it's clever enough to pull out the event handlers that are relevant and you can see here it's only pulling out our own ad to do clicked event handler which is the one we want and that's simply because the event the event args match this expected event handler we don't get the other come back over here we don't get this one because it's using a different set of event args okay so it's very very nice i mean it really is helping you along here and we'll just close out that tag like so and you can see via hot reload adds it to our pane here you could of course rather than using this you could close out with um something like that toolbar item that's valid as well but can a shorthand if you don't need to nest anything is to do it like that it's just a bit cleaner it's up to you what you prefer though now you can add other things in here like images instead of having just text you can add icons and things i'm just going to leave that for now and we can maybe do that but later if we if we so choose but what i want to come on to now is really the main event of this page and if we come back here i want to basically create this collection view that's going to be the the render source for our api call all right so come back here we'll do that so we want to specify a collectionview and we'll give it a name and the name is what we have here so i'm going to copy that just to be super super careful and so this is the collection view we want to populate give it a selection modes and selection mode you'll get a little bit of help here you can either select multiple items at one time or just individuals we just want individuals and then we want to also wire up an event handler so selection changed and you can see here again visual studio is clever enough to pull out the relevant event handlers that match the required event arc so this is our on selection change the event handler so very very very very nice so we'll run that out and then we basically want to render out our items to screen so collection view item templates there's a little bit of nesting here and then we want a data template and then finally we want to write out our line of text which is our label set the text property and you want to use binding there's me uh over helping visual studio by putting in additional brackets we just need to type it once um so binding what do we want one bind to the property name to do name and we can set things like font size so let's make it a little bit bigger so font size medium we don't want it too small we don't want it too big and we'll leave it like that for the moment this is going to be pretty basic let's save that off so what i want to do is we'll probably have to stop the app because i want to change the code here uncomment this and we will rerun it in fact let's see if pot reload is good enough to work without it let's save that off and yeah here you go making asynchronous methods which we are here then handle it requires restarting the application because it's not supported by the runtime so again hot reload is brilliant for what you know design work and stuff but for certain things you do need to actually stop and restart the app so you can see when you get this purple squiggle under anything that's really saying yeah you've got to stop and restart the app which we need to do anyway so that's okay so let's just do that and we'll restart and the two things i want to test well so a few things we can now test we're able to test the click event handler here and we should get our items rendered here so this is a bit of a watershed moment in our build it really is bringing a lot of concepts together so fingers crossed that it works okay so let's start that off let's just do a build before we run it just to make sure we don't pick up any to see if we can pick up any issues before running that succeeded so let's start up and see what we get fantastic there we go so we've got our two end points uh two end points or two to do items from our api and just to show you uh insomnia just to show you that's not some kind of weird bug that's duplicating items i was pulling insomnia over onto the screen if we get all to those that's the to-do items we have in there again if we add another one yeah we can see how that works but that's cool that looks pretty good what you'll see though is that i mean this looks rubbish at the moment we've got our two end point two our two to do items crushed up against each other it doesn't look very nice um but we'll we'll take a quick pause here and we'll change some markup we'll do use hot reload again to change how that looks just before we do that though i do want to just change a change i do want to just check our event handles are wired up and we can do that so if you click on add to do we get our add button clicked which is excellent and if you click one of these we get our item change clicked as well so that's fantastic so got to a good space here now we've actually made use of our rest api we've made use of our data service our event handlers are working um we just need to tidy up the ui here before moving on to our next page which is our main page so good job if you got to this point if you get stuck just remember the code is on github so you can download that and compare what we've done if you want my view it's going to be either networking stuff or just some really simple maybe if you cut and pasted code to save time like i've done um you may be just not quite putting the exact things like the right event handler arguments and stuff like that but um anyway good job if you got to this point we'll take a quick pause and when we come back we will rejig this ui to make it look a bit better but we'll do that next all right so back over in our app we want to kind of change the way this looks a little bit it's not it's not looking particularly amazing is it and you know don't get me wrong we're not going to have an absolute world world-class user interface either but it's going to be much better than what we see here now fundamentally the structure of what we've created here the collection viewing and the collection view item template and stuff is not really going to change much this structure is is okay but what we do want to do is add in some additional attributes that will allow us to change mainly things like the margin padding so for example in our when we specify our collection view we can also specify a margin and i think you can put this anywhere yep margin and you can just give it a value that will there you go place a 30 presumably as pixels margin around the collection view itself so you get 30 pixels from the top 30 pixels from the left 30 pixels from the right now you can change it you can supply that rather than just seeing a blank at 30 and we'll just wait for that to well actually you have to put a value in you could say if we want 30 pixels from the left we don't want anything from the top we want 50 from the right and nothing from the bottom you will see that you know hot reload works but you can see we got 30 here 50 here zero here so you can supply it like that and really delve into the granularity so this is left top right and bottom or you can just supply a single value and i'll just get applied to all four of them okay so that's applying a margin that looks a little better already but that's just being applied to our collection view our items are still very crushed together so we want to put a bit of margin around those as well so there's a few ways you can do it i'm actually going to take a slightly different approach rather than applying a margin like that i'm going to introduce something else called a collection view items layout so collection view items layout i just want to take a new line just to give me a bit of breathing space there close this out and in here you can specify a layout build layout scheme for our items here and so in order to do that we can say linear items layout specify the orientation horizontal or vertical so let's say vertical and we can say item spacing and just give it a value let's see i don't know 30 again see what that looks like and close out the tag there you go that's maybe a bit bigger isn't it so maybe 20 is that better but better okay so that looks already much much better we've got our items kind of almost centered in the screen here and they have some distance between them now i've just literally scratched the surface of the kind of things you can do with xaml it goes much much deeper than this if you want to maybe delve into in a bit more detail then i'm going to go into here check out the microsoft learning path uh it's actually really pretty good and i put the link in the description below just click on that and go through some of their learnings it's pretty decent all right fantastic so i think we'll maybe leave that there for now and what we're going to come on to and attempt next uh or succeed that next we're going to attempt that we will attempt and succeed at it is add our second page which is our manage page to allow us to add items and delete and update items so we'll take a quick pause here and then we'll do that next so maybe before we jump into adding our new page let's just do a bit of a sense check on where we're at just to kind of keep us keep us straight so we have done our model we've done our rest data service i think as i've already said we have basically finished our main page xaml we've just finished that in the last section we still have some stuff to do in here in the code behind because at the moment those event handlers that are handling the ad event and the changed event they're only writing a message to screen they need to redirect us or routers through to this page here this managed to do page so and that's really what we're going to do in this section we're going to work here and then come back here a little bit just to finish off the code in those event handles as part of adding this page we're going to need to touch our app shell to add a root and we're also needing to register this in the same way that we did for main page we're going to have to register our second page in my program as well so it's available for dependency injection as it too will need to ingest a data service in in this same way all right so that's what we're going to do over the next few sections so i'm going to stop my app from running i'm not doing too much ui stuff at this point in time so let's just stop that and come back into an application so what i want to do actually is add our new page and before i even do that i want to create a new folder and we'll do add new folder and we'll call it pages okay and you can call this anything you like it's just a folder obviously but i've seen this called views i've seen it called pages i personally prefer pages given that well i believe we're actually adding a page into here as opposed to a viewer which when we went through our ui architecture we just bring that up again um not that one let me just make sure i've got the right one selected this one here and we have this kind of shell page view and i i personally think this is a page that we're adding that will contain views so that's why i like to call this pages and also might get a bit confusing if you've done model view controller stuff as well so anyway going down a rabbit hole with that but call it what you like i'm going to call it pages and then into this we're going to add a new maui page so add new item and because we have the mavi workload installed we get this set of murray templates and the one that we want is this one here the content page xaml choose this one because if you choose this one you get the xaml page and the c sharp page i think if you just choose this one you only get the code behind page which kind of makes sense because i think as i said before you can just do everything in c sharp so if you add this you only theoretically need c sharp to do even the mark not markdown but do the ui display if you choose xaml you actually need a c sharp page really in order for it to be fully functional so that's why you get the two with this one here so i'm going to change the name from new page to manage to to page and we'll add that so in this section we're really just going to do a bit of wiring up we're not going to do anything too clever with it we just get if we just want to look at that you just get a very simple page with you know the title of the page and you know a label saying welcome to maui now actually this has just reminded me you can see here there is a title attribute that tells us what the title of the page is i'm going to leave that for the moment but it did remind me to come back over to our main page xaml and put in a title for that as well because at the moment i think it just says something like home doesn't it from memory uh so the title is going to be my to-do's and hopefully if i remember we can point that out when we next load the application up but i just wanted to do that this just reminded me that i wanted to add a title there but let's just leave that for the moment we're not going to do too much else with that right now and what i would like to do is create a route to this page which we will need and also register it for dependency injection so where you create a route is in the c-sharp code behind for your app shell and it's pretty straightforward we just say routing register route let me just give it a name of whatever the class name of our page is so it's manage to do page i believe let's find it if that's right yep so let's find it and here it's type of manage to do page perfect okay so name of and type of and in both cases it's managed to do page that's it that's us added our route and route we'll you'll see how routing will come into play well very soon actually when we come back to our main page code behind we need to route through to this page when we click on both of our event handler method so when we click on both of our ui elements that invoke our event handlers is probably a better way of seeing that and then the other thing from a kind of wiring up perspective is to come back to our murray program class and in the same way that we registered our main page as a singleton we need to register our manage page as well but because it's a more arguably transient type of page that gets displayed on and off instead of by adding a singleton we're going to add transient to that and we will register manage to the page and i guess we'll need to bring in the namespace for that as well okay so it's found that that's cool so again i do have a free module on my.net developer toolkit course on livejackson.net it goes through service lifetimes and things like that so we talked about scoped singleton's transients that kind of thing if you want to really get detailed um knowledge of that check out just register it's free um very high level singletons of a long lifetime for the lifetime of the app transients have a lifetime i think foreign myself for each request each unique request all right so that's good so that's really our kind of wiring up this page is still a very vanilla page at the moment well maybe take a pause there and then what we're going to do next is we're going to come back to our main page and we're going to make sure that when we click on those two buttons that it actually navigates us to that page and renders that page but we'll we'll do that in the next section so moving back over to our main page cs file or code behind file what i want to do in this section and achieve is to update our two event handlers to actually navigate to our newly created manage page now the manage page is still not going to do much it's just effectively an empty page but once we add the code to our event handlers here we can probably draw a line under our main page as the development that's pretty much done for now anyway so let's get started with that so i'm going to leave the the debug rightline and it's actually quite useful even though we're kind of confident that's working well i'll leave it there for now what i want to add is something called a navigation parameter and as the name would suggest it's just basically data that we can pass with the request over to the target page and it's basically just a new dictionary and we give it string an object and i actually don't want that i want to configure it somewhat i'll put the semicolon in here and so we're going to create or specify the string as the name of or to do class as that's basically what we're going to be setting through sending through and to bring in the namespace for that so using models and we want to pass through because this is an add add clicked event handle we're creating a new to-do item we're just going to pass through a new or empty whatever you want to call it to-do object so just specify like that i'm only doing one thing so hopefully that's going to make sense so we're creating this navigation parameter it's essentially a dictionary the string is just the name of the to-do item and the actual object itself is a to-do item fantastic now we want to pass that through this navigation parameter we want to pass it to our manage to do page and the way we do that is we make use of our shell so we want to await on our shell current shell and then we're going to use go to async i thought when i had left basic programming behind i was never going to see go to again but and we have it here it's obviously a completely different context but um so you can see here that it's expecting a title and some navigation parameters so name of and the target is our manage to do page and this is where the routing that we just set up in our shell kicks in we're naming it um the target here and because we've registered the route we know where we need to send it and then just the navigation parameter which is really just data that we want to send over with it and we just need to add the namespace for that excellent hopefully that makes sense i don't think it's too complex uh concept so yeah we'll see that working in a second hopefully and then for the on selection change we want to do exactly the same thing almost exactly the same thing not quite the same thing but as this is an on selection event change then really what that means is we're wanting to update an existing to-do item we don't want to pass over a new to-do item we want to pass over the selected to-do item so let me do that as we make use of our event args e and we select current selection first of the faults this looks a little bit like uh link canon you know terminology and as a to do so we kind of cast it to a to-do object like that and the rest of it is exactly the same we're navigating to the same page we're just the navigation parameters are now going to contain the value of that to-do object so that looks pretty good i think let's save let's do a quick build and that will save it for us excellent that looks like that's succeeded so let's let's go for it and start up so all i'm expecting to happen now is when it does eventually start when we click on the add to do and we click on the either of the existing to do items or navigate us to our new page on the other thing uh just to remind you we now have a title on our main page my to-do's before i think it's said home by default so we click on this excellent event files and it takes us to our managed to do page which again is just a placeholder and if we click on one of these it does the same thing excellent so in a really really good spot to move on to the next section which is basically to start to build out or manage to do page we'll start with the code behind and we'll move on to the xaml code but we'll um do that in the next section okay so we want to move over and start to work in our manage to do page and we're going to start with the back end code the code behind the c sharp code so let's just move over to that now this is going to be quite a longish section i'm going to just do all the code required in here so buckle up and get ready for some code it's not it's there's nothing terribly complex and here's just a bit more code than i would usually like to cram into a kind of section but um yeah let's let's see how we get on so the first thing i want to do is we want to make use of a data service as we have done with our main page so we want to inject that in through the constructor so i'm just going to specify that we want an irest data service and we'll just call that data service and as before we're just going to assign that to a private read-only field called underscore data service and we'll assign that to data service like so again this is a very common pattern in dependency injection we want the read-only field um which you'll see over and over again do need to bring in the namespace for the data service so let's just do that as well excellent now the other thing that's really important and i have forgotten this on occasion and it's caused me a few head scratching moments is to set the binding context and what is the binding context the binding context is basically saying that we want to well can i think of a better word for it bind any property values that we have in our code behind and allow them to be retrievable by the xaml page and if you don't put this in you can run into all sorts of um well issues basically and it just yeah it can drive you a bit crazy as it has done myself on many occasions and we want to set it equal simply to this okay so binding context equals this and that's our constructor complete which is cool i do want to come back up here though to our um fields that we want to have i want to create a couple others so i want one for to do and i'll just call that underscore to do and that's going to allow us to kind of track a few things around our object mainly whether it's a new one or an existing one and we're going to make a bit of a determination on um what our save button will do but we'll come on to that in a bit and a normal one is yeah around that same concept is to define another boolean and we'll call it as new and this will just use it we'll use this to determine whether it's a new to the item or an existing one this has auto-corrected to something completely bizarre so let's just um bring in the namespace for our model i'm going to create a property that will basically represent this private to-do element here but before i do that i want to create one more thing this little support function called is new so return of billing we'll call it as new i'm just very used to defining variables rather than method signature so it is new and it expects a to do item call it to do and it's just going to check whether yeah his name would suggest we have a new item or not the way we're going to do that is by looking at the to-do object passed in and we're going to examine its id because we're using sql lite and even if we're using sql server and ids generally are not nullable that will always have a value and by default a new um object with an id or sort with a with an integer will have a value of zero that's assigned to that integer so if it's on your to-do item id will be zero most typically if it's an existing item then it will have a positive integer that's assigned to it by the database layer so the check is very simple and so simple in fact that visual studio's already guessed what we want so if to do id equals zero that means we have a new item okay so we'll return true not false that would get really really confusing we get the opposite behavior otherwise we just return false okay so this is just a little simple support function nothing else excellent and then i want to define a property and we'll call it to do and we'll just update the getters and settle so the ghetto is fairly straightforward we're just going to set it to the the private instance we have here okay fantastic the set is a little more complex so requires some curly brackets and we're going to say is new equals and we make use of our support function is new and we just pass in the value that we're trying to set okay so that's determines yeah with in you or otherwise and then we just assign the value to to do like that other thing we need we need to raise an on property changed event and this is required when it comes to updating an existing item we need that to reflect and actually manifest that value or to do string in our ui if you don't have that that will not appear so make sure you don't forget the on property changed event fantastic all right so in a pretty good shape there what we're going to come on to doing next is to define the event handlers for our ui and we're going to have three buttons on screen here one called save which is just going to save whatever we've done and that's going to have to have a little bit of logic in there because we need to determine whether it's a new item if it's a new item when we click save we're going to call the relevant method on our data service if it's an existing item we'll call the second or another method on our data service to update so we'll have our save buttons we'll do an event handler for that we will have a delete button self-explanatory another cancel button which is just going to take us back to the previous page before we do that however and i should have probably done this right at the top of this section coming back to our main page we in the last section we put in these lines here where we use our shell to basically go to whatever target we are specifying which in this case is our managed to do page and we were passing these navigation parameters at the moment when we navigate to this page there is nowhere that page can catch those navigation parameters we need to allow it to kind of receive those navigation parameters so we do that here and we do it by decorating the class and we decorate it with something called a query property okay and this is really super required if you don't have it none of this will work so name off to do and then the query id just specify that as to do as well just to keep it really simple and you'll see how that will manifest in a little bit when we start actually using it but this is required absolutely mandatory decorate the class with this and that means that it will receive any navigation parameters excellent so let's start with our event handlers for our buttons so async void let's do the simplest one first we'll do our cancel button so on cancel button click there's object sender and just vanilla event args and all we want to do is just navigate back to where we came from to our to our home page effectively so we'll use our shell again current go to async but rather than specifying the name of the class we just use this shortcut here which is double quotes dot dot semicolon and for those of you who are i mean i think of this like i'm almost like going back a level really that's really what it's doing so if you've used command line linux command lines or even link powershell as well i mean cd dot dot you go back up a directory level that's basically what this is doing okay fantastic so that should work okay let's do our delete button now so async void on delete button clicked object sender and event rxe no we e all right and we want to make use of our data service so not that oh wait uh underscore data service and we're going to call our delete to async method and we just need to pass over the id of that if you remember so we're going to make use of our to-do property and we're going to access oh i just realized spell that wrong so i want to use the to-do property not the to do class so that should render that that's better um and that's it and then we just navigate back to the root or navigate back to where we came from so there we go all right so again wait on our data service we just need to pass over the id of our to-do and we were using our to-do property and i had named that incorrectly but sorted that now um excellent and then the last thing you want to do is the save button so async void on save button clicked object sender and event rxe and this is a little more complex because we do need to make the determination whether it's a new item we're adding or an old one so we'll say if the property that's passed in but the property that we have is new then we're going to call the add to do async method otherwise it's an existing one we just call the update and it would help us build else correctly there we go fantastic so i might do a debug write line since this is somewhat more complex so debug dot you know in the name space for that control period right line you don't have to do this of course i'm just doing this because if i've made some kind of stupid mistake it's just easier for me to understand what's going on so um add new item cool and then we just wait on our data service pretty straightforward from this point same sort of idea on the data service and we just want to call add to do async and we pass in the whole property to the property rather than just the id like we did for our delete and then don't forget to navigate back and in fact we could probably put the navigate back outside because um we're doing it in both cases so let's just do that right let's just copy it so irrespective of whether whether we're adding or whether we are updating we're just going to navigate back anyway so i'll put that there i'm going to copy this paste this in here and update an item and we'll change this to the update and point the update method there we go and it just expects a full object as well so i think that is our code behind done let me just double check the critical things let's go over it again the critical things that you need you need this query property at the class level you obviously need the data service that's self-explanatory but you need the binding context as well absolutely need that i mean you need everything here for it to work of course but those are the kind of little gotchas that you might omit and if you're not paying attention and then the rest of it i think is fairly self-explanatory so i think that's from memory that should be our entire code uh behind class done for our manage page in the next section we'll come on to doing the xaml user interface and we'll tie all this together but we'll do that next all right so let's come over to our manage to do xaml page now because we're going to work pretty much exclusively within this in this section so let's just start up our app because yeah i want to use hot reload as we design this page out as per microsoft's recommendations perfect so let me just move this over so we can see both our xaml code and our app so we click on the add to the button this is the page that we're now editing so we're going to do a fairly basic layout all the layouts i'm doing are fairly basic to be honest with you but we're going to do one variant of a layout in this section and then the following section will maybe change a little bit we're going to continue to use vertical stack layouts um but i do want to remove this label which is just this welcome to.net mavi thing here so we just delete that that should go and i also want to just slightly change the title not not by too much but i want to take out reference to page and i just want to put spaces in between here so manage to do and maybe pluralize that managed to do this that's better but we're going to retain the vertical stack layout and again vertical stack layout just puts controls one on top the other in a vertical action stacked so it's named very well so let's begin by specifying our first control which is a label we'll give it some text and this is just prompting the user to add a to-do item so let's see what do you want to do question mark and we'll just terminate that so you can see straight away the label is pressed right up against the left most edge and also the top middle at the top most edge of the viewpoint you're playing which we don't want but we'll leave it on that for the moment because i just want to show you how horrible this will look the next thing we want to pull back is or create is an entry field and the entry field will either be empty for a new item or it will contain the existing item of our existing to-do so the control for that is an entry and this is where we use binding as well and where we use binding is in the text field so it too has a text property but we want to bind it to our existing to-do property name if we have one if we don't have one it will just be empty so text curly brackets binding and then we specify path and it's just to do to do name and that should render any values that we have in order to do property that was passed over and via our query property back over here back up through our query property we can access that and we access the property name to do which is the text that we want and we can also do things like add a placeholder and placeholder text is you know you've got a text box but there's text and it's not really text in it but you know that kind of again sort of like a suggestion you get what i mean so we'll just say item or something like that and then we'll just terminate that off as well and that has appeared on screen you can see enter item and i think that's well we'll find out whether it's working correctly because i did click add new items so there shouldn't be any binded text um again we're working on hot reload it may not have worked anyway even if we clicked an existing item but we'll find out we'll test all in a minute but the point is we've got this label we've got our entry box they're all pressed up against each other it's looking pretty horrible at the moment and then what we want to then add is our three buttons so not surprisingly we start creating button controls give it some text first one will be your save button and we just want to subscribe our clicked event handler to our on uh save button clicked okay so pretty straightforward don't think there's much more explanation required and we'll do delete here and then on our clicked event handler is on our delete one and then finally button text cancel and that's just on the cancel clicked event handler perfect so we can start to test these out to see whether they have worked brilliant so functionally speaking we could probably start testing this now and adding items and cancelling and deleting items but before we do that you can see this looks pretty horrible it's not a very nice user experience so all i'm going to do is just create some margins around some of these items just to improve the flow and improve the layout and so this blob of buttons doesn't look completely smashed together so probably the simplest way of starting to do that is to provide a margin for the entire vertical stack layout and again i think i went through this in one of the last sections you can by just applying one number it will apply uh 20 pixel spacing to the left the right the top and the bottom which has happened here so that looks already a little bit better still not perfect what i want to do though is just apply some marginal styling to the buttons anyway again there's lots of ways you can do it the way i'm going to do it here is to specify some styling just for our buttons and the way you can start to do that is to make use of a content page and use something called resources and this is kind of more a global set of settings for the resources that you have on your page and inside of that i want to specify style target type is button so i'm just targeting a button controls and then on that we make use of a setup property what property do we want we want margin so again you can see that you could you know include any number of properties that will allow you to visually change the layout or look of your buttons i'm just doing margin to keep it simple and supply the values for that so again you can just go something like um five and we will just uh terminate that to see what that looks like and that will do that that looks okay or you can go into a more granular level and do something like we don't want anything from the left because we've already got a margin on the left uh we'll do five from the top nothing from the right and five from the bottom and that will probably look uh very similar in fact to what we already had okay so you can do it any number of ways i think that looks better fantastic so let's save that let's see if this works now so maybe navigate back we'll click add to do and one thing i've noticed i don't know if you notice that if we click add to do it still kind of initially renders the original page so i think obviously there's some kind of caching with hot reload so i would personally feel more comfortable let's try it let's be brave and see if it will work um do next ui layout save that it does okay that's excellent so it's actually is is working um yeah it is working you just see that again although if you can see that you just see that initial old page and then it flips back and that's purely because working in hot reload mode when we fully reload it you won't get that um let's just check our update functionality this is getting quite exciting now save that off excellent that's working as well and let's just delete this let's cancel that's cool and let's delete um delete's not working let's have a look what have we done what have i done wrong here let's see what i've done wrong hopefully something okay none to xx response so that's coming from our data service let's just take a quick look at that so maybe we stop our app running let's take a quick look at our data set let's see what i did wrong here come to the delete here's the delete um oh okay there we go i think that's what it is yeah there we go so the url that we built out i didn't put a forward slash in there okay so it was just to do and then the number it wasn't actually going to the proper route um yeah so they are for the this is the update one let's get all let's get oh let's get all to do is um update one here on this one i want um yeah okay so we have to do it forward slash okay that's cool i think that's what the issue is but let's just double check so let's save that let's re-run it and we get our same items click on that excellent and you'll notice the difference now we don't get the the ghost of the old page if you just click delete it's deleted excellent fantastic so we've actually you could almost say we have finished and in fact really that is the functionality of the app done completely so well done if you've got to the stage um quite a lot of work to get to the stage but we've ended up with quite a nice little app you could of course build out the two do modeling have a lot more attributes on there but again i deliberately didn't do that in this video however i'm not finished because two more things i want to do i want to go through and maybe do another ui iteration on our ad page we'll do that in the next section and then the last thing i want to talk about is http um http uh client factory i've forgotten the name of it i think that's what it is um right http client factory yeah i think that's right i use it so often i've actually forgotten the name of it so anyway if that's not the right terminology i'll correct myself in that section but yeah we'll do the reiteration of our ui in the next section okay so this section we want to slightly rejig our ad to do page so i mean this is okay it's working fine but i want to take these three buttons and i want to arrange them along the bottom of our screen there and that's going to as we've got three buttons we're going to have three but basically one of our grid and then make use of a table as well we're gonna have three buttons along the bottom here and it's just going to look slightly different so it's just a bit of an explanation of a different ui approach before we do even that the one thing that i've been a bit remiss on is we've only been running this app in android to date and the whole point of my way the whole value proposition in my way is that you can run build your code base once and then run it on multiple endpoints or multiple platforms so let's take a quick look and just see how this looks on windows just before we move any further with any other development i'm going to select windows machine and click run now there's absolutely no reason why this won't uh work of course it will but the main difference i found was all based on that networking stuff you remember when we did the android config that's where i found the differences between windows and android i don't really think that's a maori thing it wasn't really anything to do with the code base as such it was more just to do with yeah networking anyway this app has started on my other screen let's just pull it over you can see it has the same endpoints does exactly the same sort of thing save that off we can delete end points and does exactly the same thing just looks a little bit different as per windows um i guess ui guidelines you know to do in that way based on windows but these are obviously using all the same code really test on windows cool so i'll just show you that it's kind of the main point of maui um and there you go unfortunately i can't run on ios or mac i don't have access to either uh those of them access to mac at the moment so i will have to maintain with windows for now but the same code base would absolutely run on those as well excellent so just thought i'd show you that before we move on and yeah what we want to really do now is revisit our xml xaml page or main page and just rejig the layout and i'm going to move back to android though because i just feel it's a bit easier to work with in my current screen configuration it just fits nicely on the side there so let's start that up and i'll just not minimize it i'll just um just drag this over a bit so we can see this and let's just get our ad to do page up because this is the one we want to change and let's come back over to our main page xaml fantastic okay so we're going to get rid of these content page resources and we're going to get rid of our stack layouts and i'm kind of noticing that the hot reload isn't really you don't want to do that and leave the content page so you have to be really careful when you're deleting things we we still need the content page um does this do anything okay this looks like hot reload is kind of no it's not kind of picking up so what we might do might just stop the app and just just do the code and we'll come back and look at what it's like it doesn't look like the hot reload stuff is kind of doing um what i was expecting it to do so we'll just rework it here first and then we'll load up gives us a bit more room on screen anyway so the first thing i want to specify is a grid again just another tag grid and we'll set the row definitions and this is really just talking about the spacing of the rows sizes of the rows and i just want to go with an auto scheme so star comma auto column definitions same sort of idea i just want auto determined by the device at hand so we'll use that for our three columns and then call them spacing we'll just set that to five inside our grid we're going to create a table view and you can specify an intent you get these different intents here ours is just going to be a data intent and then we'll specify the grid row 0 and the grid column span to three because we want the columns there we go that's our table view so inside our table view we will create a table root and inside your table root you can see this can get nested quite deep we will want a table section so i'll be suggesting that for us with a title and this is just where what we had in our label in our previous layout we're just going to put that in here so this is going to go into our table section as the text for that let's paste that in here what do you want to do and we can get rid of this label now we don't need that anymore i just wanted to leave that on there just to show you what the analogy is in this layout and then inside our table section we want to have basically our entry our entry code but it's not actually an entry control it's something called an entry cell but it's analogous to that and just make sure i capitalize the c so we're still using the same text binding exactly the same and we're still using the same placeholder but we just needed to change that to entry cell and then just after the table view i'm going to cut these i'm going to paste them in here so after table view but still inside our grid we're going to have our three buttons but we do just want to specify their positioning so everything else will say these two attributes will stay the same text and clicked will stay the same but i do want to specify a grid role and i think yeah just be careful you don't destroy your click event handler let's try that again a grid row grid row and that's going to be one and in the grid column we want to put this button in the first column so zero based so grid column i don't need a comma old habits die hard grids call them um zero and leave the clicked event handler as it is that's cool so what i might do because that was a little bit painful watching me type that i'll just copy these two parameters here and i'll just paste them in here but we'll change the values of the column for each one okay so grid row stays the same we want it on the same row but this one is in position one and this one is in position two excellent so let's save that off and we'll restart our app and we should see what that looks like now again functionally no different it's just we're changing the ui slightly so let's do an added to do and you can see your buttons are down the bottom here the only thing i don't really like is the buttons are pressed right against the bottom edge and right up against the the left and right edges which probably not that nice so let's how can we change that let's maybe put a margin let's use hot let's see hot reload works for us it should do let's put a margin in here and we'll just make that equal to uh we'll do 20 on the left oh look at that and we'll say zero here that's better okay and we will leave our middle one we'll leave delete and we'll put the same thing in on here margin 20 zero it's better what about if we put five in here again this is this is all the kind of stuff you can play around with yeah you need to do it for i'm not sure i kind of like it slightly off the bottom i'm not sure i like it right on the bottom edge so i might put margin and zero and five in here like that i like that more i don't know about you it's up to you again the whole point of this is ui i think is somewhat subjective and i'm certainly not a ui guy as you can probably tell but everything else is working okay so um http client factory is next it's just there's no reason why the functionality should not change it's just ui stuff cool so two very simple layouts for our um our manage page um and you can obviously go deep and change uh you know change it to how you like it to look fantastic so the last and final section of the video today is i just want to do a very very very quick section on http client factory before we wrap up and close off so we'll do that in the next section so in this last section i just wanted to circle back to how we've constructed our data service class and maybe i just stopped our app from running and i can just poke around the code and just show you what i'm talking about so we have our rest data service and via our constructor we are creating a new http client we're newing up in here okay now typically i would never do that in most of the applications i write whenever i'm using http client i don't get an instance of it in this way i will use a http client factory to get an instance of http client that's the way i do it and the main reason for that is the client factory manages connection threads and all that kind of stuff so you don't end up with connection exhaustion and all manner of issues now possibly in an application of this nature you're not going to end up with that and when you're maybe dealing with you know the android subsystem for which i'm not an expert by the way or even the ios subsystem maybe the way they deal with connections is so super amazing that maybe we don't need to worry about it however just the way i've kind of been i wouldn't say brought up but the way i've come to understand http client i would always rather use a http client factory to manage my instances of http client in every instance even for small apps so that's what i want to pivot to in this last section we're going to use http client factory i'm wondering how many times i can see http client factory but that's what we're going to do here so if you're interested in doing that as well and hopefully i've explained the benefits of why you may want to do that then we can do that in this section so the first thing we're going to do is we'll need to install a package so it's microsoft extensions http uh it's this one here okay and we'll copy that and we'll install it and just fyi again taking my way aside microsoft recommend the use of http client factory in all the um discussions around the http client they recommend that you solve it okay so um another reason if i'm exploring the option of it here so let's install a package so tools and you get package manager package manager console and we'll just paste in our install again i always take out the version you don't need to do that i just do it for my own personal reasons and that's cool that's looks like that's installed you can check the project file by just clicking on it and we should see an entry for it down here somewhere there is package reference okay so that's there that's all good and it's very very simple to implement it the first thing we need to do is just change the way our data service is registered in our dependency injection container so we'll comment that out and it's almost almost identical but that's probably a bit of a contradiction in terms you can have almost identical things and instead of adding singleton you add http client but the remainder of it is exactly the same all right so just paste that thing like that excellent so we'll save that off and then the only other place you need to change it is really around the whole point of what i'm talking around is here we're not going to new up http client any longer we are going to get it via drum roll constructor dependency injection so we just ask for one from our dependency injection container and we'll call it http client and we just assign it to our private instance in exactly the same way that we've done for other uh dependency injection um services that we've required and that's it okay so we just we're not we're no longer newing up we're just getting it given to us and it's managed for us okay which i personally prefer so last thing to check is just to see whether it works there's our app starting up and yeah well certainly retrieved all line points uh let's uh click on that and say done something like that that's not even close to seeing that but doesn't matter i'll save that off yeah it's all working fine so again a totally optional section but for me personally this is how i would continue to do unless i'm told otherwise for some really strange reason not to do this this is the way i would personally do it although the other way the first way we did it was fine as well anyway that brings us to the end of another video i hope you enjoyed learning about net memory as much as i did i learned a lot about it as well because i had to do a lot of research to get this up and running but i've enjoyed it very much indeed and again thank you for joining me you've not done so already maybe think about subscribing to the channel and you'll be notified especially if you click the little bell of any changes or any new videos that i make until then though stay safe and i'll see you again next time [Music] [Music] [Music] [Music] [Music] you
Info
Channel: Les Jackson
Views: 102,605
Rating: undefined out of 5
Keywords: .net, maui, les jackson, httpclientfactory, tutorial, api, rest, step by step
Id: LrZwd-f0M4I
Channel Id: undefined
Length: 203min 17sec (12197 seconds)
Published: Tue Aug 23 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.