MVVM, Databinding and Dependency Injection - .NET MAUI Tutorial Step-By-Step

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this part of the.net maui crash course we're going to learn about mvvm data binding and getting our monkey data from a remote source [Music] now before we dive into the world that is mtvm and data binding let me do a quick note that this video is part of a full course a crash course on.net maui so the playlist should pop up on your screen right now or find a link down below um but just so you know i would highly recommend watch the other videos as well so that you know what it's about and what we're building just wanted to quickly point that out now mvvm and data binding that's kind of like where the magic begins for like most microsoft products because a lot of microsoft products are using this right so that's the good thing as well if you understand how it works for one platform then you already know how to work with it for down at maui as well but let me just go over the theory here for a little bit before we go and see how to actually implement it in our monkey finder application now while it's called mvvm it makes more sense to me to put the view first than the view model and then the model so vvmm but that doesn't have the same ring to it i guess but let's start with the view right so the view is kind of like your outside thing that is the user facing thing that is the thing that you click around tap on and um that is also the thing that doesn't want to have a lot of logic right because if you start writing logic inside of your view um then things can become tangled and it's hard to kind of like do unit tests because all your code is dependent on the ui and for unit tests you don't have a ui typically so that's not great right and also if you want to kind of replace that view or maybe you're going to implement a b testing where you have different views maybe randomly or depending on some condition um then it's not really great because now you have to duplicate that logic because all your logic is in the view right so that's not what you want you want to view just you view things and interact and pass on signals to the view model and in your view model that's kind of like you also don't want to connect like everything from your view directly to the models and your services and whatnot so that's why we have this view model because your view model is responsible for catching all of those signals and switching around basically properties and those are a lot of properties that can have to do with how things are viewed right inside of your view how things are presented so you don't want to clutter all your models that might end up in a database with things like hey is my ui currently busy or what kind of background color should something have right that's not things that you want to have in your database with your models with your data so that's why we have the view model there in between that has kind of like all the logic that is needed for the view but it's also like passing on things to actually the model where your business logic and that kind of thing is so from your view model which is a representation of the screen basically that you want to show tied to one view and there is all the properties and all the signals are going back and forth and actually that's happening through data binding but i will get to that um so and then the last thing kind of like is in in this pattern is the model right so that's where you do all your business logic that is where you are going to persist things to the data layer or all that kind of stuff so that's how that all fits together and then there's one ingredient that's not really in the mpvm name but that's a binder and that has everything to do with the data binding and in the microsoft world the binder is usually xaml you can definitely also do it in code if that's what you like but typically you will see that everything is done in example and what that does is again if you are using events um then that is tied to your view right you have to have that event know the actual control that is firing the event so there will always be the tight coupling and or you want to reference to controls directly so you have to give your controls a name and again then you're going to tightly couple your view with the logic and that's not what you typically want if you want to reuse your code or do unit testing or do any of the stuff that i just mentioned so how else could you do that well data binding is kind of the answer and with data binding you're basically just going to say like hey i have um this property on my view so for instance let's make it very concrete in our last video we had the collection view and we had that item source right and in that item source we could say we had this this this kind of like static array in there now but in this video we're going to see how we can use that item source and we're going to say hey i want you to get your data from a property that's in my view model now um it will become more clear whenever we go look at some code but then from that property whenever that property is populated the view will automatically see like hey okay something is happening here i should do my new layout i should update to actually view that data so you know you're only going to loosely couple if you will to say like hey it's referenced by this kind of property name in my view model and that's also where the confusion starts for a lot of people like there is coupling you are referring to property names in the view model but it isn't really like checked at a build time right there are tricks for that which we're going to see so that you can actually figure out if something is wrong in your properties but that binder inside of the example a lot of stuff happens that is not really clear unless you really know about it and a lot of that has to do with the i notify property changed which is an interface that can signal to the view like hey something has changed i notified property changed a property has changed on my view model and in example it's built in to you know hook into that interface to look if um something is there if something's being signaled like hey in the view model something has changed an example will then see hey does the view model actually implement that interface whenever it does it will register for updates and whenever a update happens the example knows that it actually has to update its views so this kind of like sounds meta and and theoretic and abstract maybe um but hopefully when we get to some code it will become clear how this all fits together so um let's actually just stop with the theory right now and let's see how to do this in our monkey finder application so here i have started visual studio 2022 and this is exactly the point where we left off if you remember correctly we have the repository so this is basically the folder step 2 mvvm so go open the solution for that one and here we have i have it running on windows right now we can see our three monkeys which we can see here in our view and main page and so here we have like that that item source that i just mentioned right with now a static array with like three records in there and this is what we're going to change to actually get the data from a remote source on the internet and also get rid of this static array and and filling that data from our view model so if we go back here to our project structure basically and we opened this and then i stopped running the application for a little bit then we have you can see here the folders already we have the view and the view model and the model right so we already did something with the view for the main page we already did something for the model we have the monkey right here and now what we need to do is get our view model up and running so that we can tie all the things together so actually let's go to our view model folder right here and you can see this base view model right here which is going to be the base for our other classes right so we have this base view model because if you're going to implement things like the i notify property changed then you probably want to do that in a base view model of which the rest can inherit so that they are automatically implementing that as well because we have some some tricks to do that so here if we want to inherit or implement an interface we can say here i notify and it should probably come up here i notified property changed so we can just do this and then it will start complaining that we don't implement all the things in here right because that's how an interface work we need to implement all the things so that whenever someone hooking into the inode 5 property changed like your example binding engine we'll know what properties and what methods are there that it can use so we can right click this intellisense or we can do the little light bulb here or you can right click it and do quick actions and refactorings and then you can say implement interface and it will give you all the things which is in this case only just one thing and we have this property changed event handler and this is going to be fired whenever a property is changed well actually we need to do that ourselves but near the end of the video i'm going to show you a little trick that will you know allow you to do it much much easier and save you a lot of code so make sure to stay tuned but actually you know we also do not want to do this all manually so what we want to do next is implement this thing to actually trigger this right and what we can do i will paste in a little bit of code here is we just want to have this little on property changed here which we can call whenever a property or whenever something has changed and this is like made a little bit generic um so what you can see happening here is we have to pass in a string for the name of the property that has been changed on our view model now a little trick that we can do here is specify the attribute here the caller member name and that will automatically fill in the name of the the calling property so whenever we call this on property change from a property we will see that in a minute then we don't need to worry about this name because it will automatically get the name through this attribute and it will know like hey the property monkey name has been changed has been calling this on property changed so this name will automatically be populated by monkey name and what it's then going to do is going to hook into this property change thing here and see if it's not null right so see if anything hooked into this event if anyone wants to receive the signal for this event and then it's going to invoke it with this and the new property changed event arcs with the name that is coming in so now we have kind of like a generic way of signaling the view that something has changed in our base view model now if we go look at our monkey details view or let's go with the monkeys view model so that's the the one for our main page you can see that this implements that base view model right so this will automatically also have all the things that we've just implemented but we'll worry about that in a little bit now what i also already mentioned is that you maybe want to have things to show if your interface is but you're busy yes or no so i'm going to implement a couple of extra things here like a boolean is busy um a string for the title that we're going to show title and then we have the rest of our code here and now let's make this into properties so this is actually a very important thing if you're going to do data binding with with xaml and mvvm and this kind of stuff everything that you're binding to from your view has to be a public property it can be a field it can't be a public bull is busy if you're going to do it like this it's not going to work and you're going to scratch your hat why it's not going to work i definitely believe me i have fallen for this you really need to make it a property with a get set at least to get right you can make it a private set if that's what you want it has to be a property else it's going to fail it's not going to pick up on it so if you're binding if you're mvvm your data binding is not working figure out if it's actually a property because that will save you a lot of headaches maybe so we have these backing fields but now we also want to have the properties and actually let me just copy again a little bit of code because this is a lot of typing and let me just put that here and it's kind of like the same for the is busy in the title so for the get we're just going to return this this private field right which is just a field that we have for for backing this thing up um and um here in the center something interesting is happening right so we're going to see like if it's the same value then we're not going to do anything we're just going to return because nothing really has changed else we're going to set the is busy to the value and here you can see the on property changed is going to be called and this is the thing that we have implemented down here right and you can see that we're not specifying this name so in this case the name will automatically be populated with is busy and for the title it will be automatically populated with title so that's how the ui knows like hey i need to reach out to the title property and i need to go through all the controls that are referencing this title property and update that in the view so that's kind of like how that works but we're not there yet we don't have anything in the view but now you know we have implemented everything on our base view model and we can use this in every one of our kind of like inheriting view models now and this is where kind of like the use of the view model gets into play as well um because you know we have this this is busy one um but you know maybe you want to have some controls that are visible based on the is busy property maybe a little view spinner loading spinner but you also maybe want to have controls that are then visible whenever something is not busy right so and this is stuff that you don't want to have in your actual models so what you also might want to have is like um public bull not is busy right or is not busy maybe that makes more sense is not busy um and then we can return kind of like not is busy right so now we have the same property um but now kind of like the inverse one there are other ways to solve this um there is also an example a a a concept that is known as value converters and which is for another day i definitely have videos on that go check that out but for now we're keeping it simple so you know you can easily create a property like this that does the inverse but then you want to signal it for both right you want to signal it for both is busy and is not busy because else the elements are going to show up for is busy but the is not busy is not going to get the signal because we're only doing on property chains 4 is busy right so what you can now do is you can still specify the name so we can also do it for on property changed and then specify name of is not busy right so now we are signaling it also for this property and it will get picked up for both um but you can see this is a lot of code um to just do these things so let me first implement the full story for like our base view model view model um and our view so that we have this this full end to end solution right here and then at the end i'm going to show you how to get rid of all this boilerplate code with the community toolkit mpvm framework which makes this a lot lot easier but for now let's focus on actually getting this to work so we're going to switch gears here for a little bit let's focus on the surface to actually get the monkey data so i'm going to go to my solution explorer and we also have a folder already for our services and in this case there is already a monkey service so let's open that up and i'm going to add some code here um so we're going to add this list of monkey which is going to be our monkey list and if you were like you know working with uh used to working with older c-sharp and net versions this is kind of a new way to introduce new objects and this is the exact same thing as new list monkey like this but you can now just leave out the type because we already know the type from the left hand side so we can just remove this one and do new so that's what's going on here just so you're not confused and we've introduced this little method here which does the get monkeys and that returns our monkey list i promise you to actually get this from a remote source so we're going to need an hdp client right we're going to need to get that monkeys from somewhere so let's also introduce a constructor here a public monkey service one key service and inside of that we actually want to introduce an http client so also here at the top let's do http client http client and i'm not going to initialize that just yet that's what i'm going to do here so you can say this http client is new http client you can see the intellisense and intelli code i don't even know what service this is anymore will kick in so now we have this http client and we can also say here so in our get monkeys we can say if monkey list dot count well actually not is zero is more than zero we can return our monkey list here from the get monkeys because we're just going to get this list once right and whenever it's filled then you can just return the monkey list right away if that's not the case then we're going to actually you know get our monkeys from a remote source so again i'm going to paste in some code here and what we're going to do is get this response through our http client and we're going to do get async this refers to james montemagno's website who has this very complicated api uh which is just a static files uh of monkeys.json which is the the exact same json file that you can find here in the resources and raw and we have this kind of like monkey data here as well that's the exact same file so but we are getting this from james's website or you can get something else if that's what you want of course and then whenever our response is success status code so this will just do an http request go out to this url get the json file and we can check here if that succeeded yes or no and you know we're mostly going to focus on the happy path with all of this code here so it's up to you to implement the kind of like error paths here but here is the status success code we're going to fill our monkey list with response.content so that's the body of our response right so that we're getting back that's the actual json contents we're going to say read from json async and we're going to deserialize that in a list of monkeys now you can see it doesn't really know what we're trying to do here so let's right-click quick actions and refactorings and we're going to do using system.net.http.json because json is now built into the dot-net framework as well and now it knows that it needs to deserialize this from the json and we get this list of monkeys now if for some reason this doesn't work there is instructions in the repositories readme again links are all down below for this step two part two where you can also do this without an internet connection where you can read it from the file that i just mentioned so if you want to use this without internet go check that out and just paste the lines in here and it will just work all the same actually let me just show you real quickly what it does i'll bring it in here and i'll remove it afterwards so what this does is um go out to the file system open app package file async it goes to that monkeydata.json then it opens a stream reader it will read the contents of that file and it will still do the json deserializer to that same list of monkeys right so we will have the exact same thing but i want to focus on getting it actually from a remote source so let's just remove this one again and what we're now going to do is well of course we are going to need to um then return still our monkey list here just so we have everything complete so now this red squigglies are happy here too and we have everything complete here so what we want to do now is actually use this service inside of our view model but let's again go to our solution explorer and here let's get rid of these resources and now i can go to the view models and i can go to the monkeys view model now nothing is in here except for this base view model right so that's what i've been implementing in earlier and now what we can do is we're going to say a public observable collection observable collection of monkey monkeys well it helps me pretty good here and actually we just need the get so just to show you that it works with an actual get and we can say here new again right so it suggests me the whole new object thing but i can just do new so that this collection is initialized now you might wonder what is a observable collection and the observable collection is kind of like a collection that has i notified property changed build in so this observable collection will also be able to hook into the example or actually the other way around the example will be able to hook into the observable collection and it will pick up whenever you do monkeys dot remove and you remove one or you add one it will pick up on that and it will refresh the data for you on the view without having you to do anything for that so that's the observable collection it will be a collection that automatically notifies the ui that things are being updated so that is great now what we also want to do is add a little constructor here monkeys view model and we want to set that title right that title is just a little ui thing that we want to do and we have this title already set up in the base view model so we're going to set this to monkey finder and now we have this nice title as well and now it's time to bring in our service so what we're going to do is actually add here using monkey finder dot services and we want to bring in our monkey service right here and and this can just be a private field so we don't need to do anything fancy here and what we want to say is this monkey service is new monkey service well there we have it now we have this monkey service initialized but can you spot what is wrong with this we're not using dependency injection and dependency injection is something that is built into done at maui these days so what we're going to do is not do this but we're going to actually say monkey service here and what we then want to do is here specify this monkey service here in the constructor and add the monkey service here so what will happen in a minute is that with dependency injection we're going to register our monkey service and that will automatically be resolved be inputted here and we have our monkey services um as dependency injection here and again that is good for your code reuse that is good for your test stability that is good for all these kinds of things i'm not going to go into dependency injection too much here i have a great video on that go check it out in the corner of your screen right now which will give you more background information if you don't know what it is but this is definitely something that you want to use if you're going to build a real world application so now we have got this setup and now let's go actually do something with that service so right here down to the bottom i'm going to add this new method right here which is again going to be get monkey's async and we're going to leverage our service in here so what i did first is scaffold here out a little bit with the is busy right so based on if something is busy if data is being retrieved especially if you get things from the internet things can be unpredictable right depending on the internet connection the speeds the server how fast that is etc it can take a little while before the data is there so here we want to leverage that is busy and if it's busy and we for some reason get again a call here because the user is doing pull to refresh a lot of times then we're just going to return we're not going to do anything else we're going to say try is busy too whenever something happens then we're going to maybe show an error but finally so this is always going to happen right whether the try happens or the catch happens the finally always happens and we're going to set this is busy to false just so that our view kind of like resets the whole is busy stage removes the loading indicator and that kind of stuff now in the try we're actually going to get our data so let's add a new line here and i'm going to paste in some code and here you can see we're going to get our monkeys which we're going to get from our monkey service that was you know injected through the dependency constructor injection here and we're going to call the get monkeys now we're going to see if the monkeys count so this is our own observable collection here if that not already has the monkeys right if it does have monkeys already we're going to clear it we're going to make it empty and that's kind of like an important one as well if you're working with observable collections what you don't want to do is create a new one right here because if you do then you will have to re-initialize the data binding which you can totally do but you know ideally you shouldn't have to so what you want to do is reuse the same collection all the time so what you want to do is do clear that will let the ui know like hey all the elements are now gone and then you start building it up again so we're going to loop through all the monkeys in the results from our monkey service or the monkeys that are coming from our service on the internet and we're going to add these monkeys to our collection one by one so that is how this works now for our catch you can do whatever you want of course but i'm just going to say a debug.writeline just so we know what is going on here whenever something actually goes wrong so let's just say unable to get monkeys and add our exception.message here just so we know what's going on and maybe we also want to inform our user because this is just this is not going anywhere right so what you also might want to do is say await application which is you know the application that we're currently running this is an object from don and maui application.current.main page and we can call the display alert here now technically you know if you are um want to get serious about mvvm this is not really great right so let me just type this first and then tell you the rest later so error we're going to do the x dot message and we're going to do the ok so this will be a dialog that has a title which says error then in the body of our dialog it's going to print the exception message and then we have one button which says ok so that the user can continue right so typically this is something that you probably want to have i don't know a little bit more informative for your users but this will get the point across now then you're probably wondering how am i going to trigger this right because we had events if you go do a button you will have like the clicked event but we can't use events anymore in mvvm world so instead we have commands and the commands kind of like follow the exact same pattern as all the properties that you see here a command is just a little trigger that will allow you to execute some code so let's see how that works i'm going to scroll back up i'm going to implement a new field here which is going to be a well actually let's do it here so that our public and private fields are separated so i'm going to do a public command or it can also be an i command for an interfaced one if that's what you want and public command get monkeys command and again this has to be a property so be very aware of that and typically what you want to do like with the observable collection you want to initialize it right away you can definitely also do it in the constructor if that's what you prefer and for commands you i don't know it typically happens in in the constructor because you know also because it can't really be done here because you're going to reference some things that are not created at this point in the c sharp code um so what we're going to do here is say our get monkeys command is new command and it's going to have to run async so you can do async here and we don't have any parameters and we're going to say await get monkeys async this this is our method right so we can just do this now there's variations to this you can always also um only do like the the method name here which makes it a little bit less for both i think if you're doing non-async stuff this totally works but if you want to do it async then you will have to do this so what we have now is a command that we can bind to somewhere in the view because this is a property and whenever we do that we can execute the code in our get monkeys async this will start running this will start populating our monkey's observable collection and as that is populated our view will get the signals that something has happened to our collection and the view will get updated so i think it's about time to actually start looking at our view and implement this stuff so let's go over to our solution explorer again and this time we're going to go to the view and to our main page this is where we already implemented the thing for our static area here so we can kind of remove this whole thing with the item source here we will get to that in a little bit the item template is still going to be the same we still want to see those same monkeys right here um and what we want to do here now at the top in our content page is kind of like the same thing that we did here with the data template and that is set our x data type which will help us with like the intellisense for all this so here in the top on our content page i'm going to say x data type is and then i want to set view model which i don't actually have yet is monkeys view model so that's like the name of our type right and then we need to add a other xml namespace thing like this one and i can just copy and paste this one basically as well and i'm going to name this the view model because this was a shorthand for all of this namespace stuff right and now i don't want to have the monkeyfinder.model but i want to have the viewmodel right so now it will start picking up it will go look in the viewmodel namespace and it will find this monkey's viewmodel so now we got this all set up and this is just a thing that will help you edit this example right here so let's save that and then here what we can immediately do is for a content page we can set a title and in that title we can do now this do opening bracket and we can say binding that's how data binding works you will have to say binding which will let the example know like hey you're now going to bind to a property on some object and we'll hook into that inodify property changed and because we set that x data type you can now here see all the properties right plus some extra ones but we can see the is busy we can see is not busy and we can see the monkeys but we should also see the title that we have set up so let's do the binding to the title now actually we want to replace the whole layout here so let's delete this collection view here as well and i'm going to first add a grid here as well and a grid you know just like the name implies you can do things with columns and rows and then that kind of stuff so we have this grid we have column definitions with stars which basically means like it will have the space equally divided so we have two columns we have a little spacing of five in between we have row definitions and the star actually means it takes up like the the extra space that is there so in case of two stars it will divide it equally and here you will have the row definition so we have two rows and one that will take up like all the space and the other one is auto so that will automatically be adjusted as we have like buttons at the bottom we'll see that in a little bit and we have a row spacing of zero so there's no space in between and inside of that we will add our collection view and you can see here that our item source now changed from this static array to binding our monkeys and that is the monkeys in our monkeys view model right here that's our observable collection right so that's how that works together now we have a selection mode of none we're not going to select any monkeys right now and we're going to set the grid.column span so this is kind of like an odd one right we're referring back to the grid so this only works whenever it's actually contained in a grid and we're going to set the column span to 2 because we had two columns right but we want to have our collection view over these two columns we're only going to use the columns for a button at the bottom now if you remember from the previous video we want to kind of add back our item template because that is the template for each of the items that's going to be shown right so every item every monkey in our observable collection is going to get that template and now what you can see is we're going to get that data binding back here this is i just pasted in a lot here this this entire item template right here and we can see it's a data template we have that x data type that's coming back um a little bit changed about the the the layout here um we have this grid and a frame so that's all like done at maui elements that you should work with we're applying a style to this so that's very cool we'll get to styling and all of that and inside of that we have a grid so no more horizontal stack layout we have a little grid going on here now with an image that has a width request and a height request but also this image is now source binding image it kind of already did that in the data template right but um this is kind of like the important thing that you want to note here is suddenly inside of this item template the scope kind of changed so while the binding context we'll get to that in a little bit for this whole page is set to the view model now suddenly inside of this item template it is just set to one monkey because we're specifying here this item source of monkeys and then each item inside of this collection view template is a one monkey so the binding suddenly changes to image and name and location um which are things that are inside monkey right so um it's kind of like this is one of the things that is the magic and what makes it a little bit hard to get started with all of this um i'm hoping to take that away but this is kind of like the scope kind of changes like once you're inside of a item template also for a list view or other kinds of layout things like this so that's something that you will have to keep in mind we're suddenly looking at a monkey object here and we have to do the bindings this way so this is set up now as well um what we want to have lastly so outside of our collection view we want to have a button to actually you know get our monkey data now so let's paste in this button let's give it a little extra space so it makes it more clear and we have a button which is just another layout element for dot net maui we can give it a text so that you can recognize what you do we have a command and this is binding back to our view model right so this is our get monkeys command that we've just set up is enabled is bound to is not buzzy so right it's going to be disabled whenever we're already loading data so that we can't accidentally tap it multiple times we're going to position this in the grid right because this is contained in a grid as we can see here we're going to put it in the row row one and then column zero so that's kind of like the the bottom left and we give it a style again styling is going to come and we give it a little margin which is you know again a little styling thing but now we have a button to actually trigger our loading of data now because we have the is busy let's do another interesting thing which is the activity indicator so let's just paste that in here we have an activity indicator again this is a built-in control for dotnet maui which shows depending on the platform it's a indication spinner something like that you can style it in a couple of ways but here we can again say is visible and now we're binding to is busy right so whenever we're busy we're going to show this loading indicator the same for is running that's kind of like if it shows the animation yes or no that's usually tied together we're going to do the horizontal options and the vertical options so we're going to set it really in the the center of like you know our our grid the the bottom row because what we're going to say here is grid.row span so it spans two rows well actually it's going to show then over the whole page right it's going to show in kind of like the the whole page and it's going to center it there and the column span 2 as well so you know we're going to see it over over the whole screen here now there is one last thing well actually a couple of things that we still need to do but for the view there is one important thing that we still need to do and that is go over to our solution explorer we still have a mainpage.xaml.cs which is the the code behind and the only thing and really the only code that you want to have here is this initialize component which actually you know inflates all example and all the things that we've just set up but you also want to do now is binding context which is like you know well it's not this actually binding context is a property that it's going to look at for all the properties that you're data binding to so whenever in this example we're going to say item source is binding monkeys it needs to know the object where it's looking for right so it already kind of knows through this data type but like i said this is only something that helps you with editing the example it doesn't really mean anything so what you really want to do is set this binding context to our view model so that it knows where to actually get the properties from so that's kind of like your only one-way connection hard reference to the view model right here and again what we can do here is use dependency injection so what we can say here is our monkeys view model monkeys view model and i can set the binding context to monkey's view model and now the only thing we need to do is set up our dependency injection actually and this will all kind of like fall together as a puzzle that we are just solving and it will start working and we will have actual data coming from a remote source showing in our monkey fighter application now to set up the dependency injection do you still a little pop quiz do you still need to know where you need to go in your application that's right our mauiprogram.cs so let's go over to the solution explorer once more and here at the bottom where i'm a little bit in the way right here we have our maui program so let's open that up and here we can actually see that we've registered our singleton for our main page already and what we want to kind of like add now is add the rest here that we still need to do so um let's get the utility sets to help us so what we want to do here is add our services as well using monkey finder dot services that's where our services are and now we can register our other things so what we want to do is do builder dot services dot add singleton which is actually i think we shouldn't register singletons for these kinds of things i think a better option is to do a transient right here so that you will get a new instance each time so that we don't get any weird results so we want to do the well for the monkey service actually we do want to have a singleton i guess but i think for the pages and the view models we want to add the ad transient transient you should look into data binding scopes data dependency injection scopes now data binding scopes dependency injection scopes for all of this but ad transient basically means that whenever a new thing is requested of the main page you will just get a new instance a singleton there is only one object that has this object in the entire application so you will always get the same service and you will also have an ad scoped which is you know i think a little less used in this context for http and web applications it's a little bit different so we have this one and let's do also the builder.services.add transient for our monkey view model there we are and now that we register these we don't really need to do anything else because our main page is already set up here and if we then go look at like our app.xaml.cs we have this new app shell and inside of our app shell we're going to have then our um initialize component but where are we actually setting our main page now i think that's happening here through our app shell if we scroll a little bit down here you can see this shell content and it's going to do this this main page thing right that's what i um kind of like explained in the previous video so we're going to have this main page right here um and from here shell now implements uh the dependency injection as well so it will resolve this main page that's why we needed to register it in our maui program and whenever you start resolving one thing and use the constructor injection it will start trickling down and it will resolve all the things basically so now i'm kind of nervous but i want to just start my windows application and we're going to build all these things and what we should see is a empty ui at first but we now have a button that we can click to actually pull in our monkey data right here and that will show the little activity indicator i'm not sure how if we're going to see that because my internet connection is pretty good but we should see that a little bit and ultimately we should see our list of monkeys well so far so good we have a little bit of a ui because i lit uh did a little bit of styling in the app shell already this button looks a little bit stylized so you know that's something that we will get to later and whenever i click this get monkeys it's now going to oh we see the activity indicator which is nice and it's going to get the monkeys from the json servers that we just saw right so we now have a couple of more monkeys that we got from the internet from a remote web service and everything kind of like falls together here and whenever i do this it should be pretty fast because as you remember we implemented that little check if we already had something in our collection and we're just going to return that so now kind of like end to end with mvvm data binding dependency injection we have created this monkey finder that pulls in actual data but gerald you promised us that there would be an easier way to do all of this well you're absolutely right so you can do everything that is needed for mvvm and and data binding and all that stuff that is inside of the box for data and maui you don't need any extra dependencies but it will require a little bit of extra manual work right because some people don't like to use framework some people would like to have full control over everything that's going on which is perfectly fine choose whatever you want but you know if you are using an mvvm framework it can make your life easier depending on the framework you're choosing you will get different features to either write less boilerplate code that's kind of like the i think the goal for the most frameworks you can do view model to view model navigation something that you don't need to worry about right now you will get all this stuff now there is the community2kit.mvvm which is kind of like the spiritual successor of mvvm lite and it's doing an amazing job it relies on source generators so basically compile time it will generate all these source uh things for you that you don't need to write yourself so it's c sharp code writing c sharp code um and it will make your life so much easier so let's have a quick look at how we can reduce our code by implementing all of that now here we are back at our base view model and i already mentioned it here like for this is busy one we don't want to write kind of like all this code right this is like from from line 8 to line 20. so this is like 12 lines of code for each property that we want to have so that will be gigantic gigantic something like that um so we don't want to do this now for this solution if you opened this one from the repository then we can already see in our monkey finder project if we right click and do manage nuget packages we can see in the installed one we already have the community kit toolkit.mvvm1 so it's already installed you can just use this straight away actually this doesn't only work for don and maui it use it works for kind of like old c-sharp project old.net projects so if you want to use it somewhere else be my guest definitely do that and what we can do now is basically remove all of all of all of everything i guess i think we can just stick with this right now and well actually we don't even need this anymore so note mind you we just want to and this needs to be properties right so what we want to do here is we can add some attributes now here we can say i want this to be an observable property right and what we can also say oh we still want to kind of like have this is not busy one we still need that one we still need it as a separate property it's not going to generate that for us so we are going to keep this one is not busy and we're going to say not is busy um which it now still knows right because it will already pick up on this is something that's being generated so it will still understand that this is a thing um and the same we can do for title so now we have an observable property title boom and it will generate all the properties for us we just need these backing fields right here and we can generate the observable properties from this now what else do we want to do what we also can do is say we want to make this a um also notified change for and we can mention the name of is not busy so this is kind of like our our little extra thing that we had like hey we do want to do on property changed for also the is not busy right we just need to add this extra attribute and boom we now also have it for the is not busy um in fact we can remove this whole thing we can remove both of these we don't need this anymore but what we do need to do you can see the base view model is not really happy and now the i notified property change isn't happy anymore as well and what you want to do this is also a thing that comes from the community2kit.mpvm we just want to use this observable object which has all the things that i just removed basically and the base view model oh we need to make this partial because that's the way how the source generators work it of course joins these classes it generates another partial class for the base view model to actually generate all the code for the is busy and that kind of stuff so now it will be happy again our observable object and we still have all the same things here right so if i run this again it will still work as it did before but now we have lot less code remember that we have like 12 lines for is busy and 12 lines for title 12-ish um we now only have 12 lines of code basically for our whole view model right so that's pretty epic and if i go here it will still all work the same but now it will work with much less code so that will definitely make your life as a developer easier okay sit back relax this was a lot to take in you have learned how to do mvvm you know what mvvm is you learn how to do data binding dependency injection learned all this stuff that you could immediately forget because now you can use the community toolkit.mvvm and we actually you know have our first functioning applications that will get monkey data from a json source on the internet show it in a nice way in a collection view in your don and maui application but this is this is pretty much a lot to take in right so a great job you did awesome today feel free to take five minutes off before you go to the next part uh no definitely not you should follow this on your own pace but i think you know go over all the steps here re-read some things that might not be clear to you immediately but i think this is a pretty good foundation on which you can build the rest of your dot in my application because this is something that will come back in every mobile and desktop application for that matter this is just a big part of how applications work these days so well done now i ran it again on windows but you know you could just as well switch to the android emulator that we've set up so that might be a nice exercise for you to also be in shock that you can use this exact same code base on android as well so switch over to that android target run it on android maybe you have that mac build uh host setup so run it on your mac your ios simulator which is pretty epic to see that your application is just running across all of these platforms so you can do that as a exercise of your own we're going to look at for the next video to navigation so that we can click an actual monkey and we can get some details there because you know now we got this data we want to kind of drill into that and then see where we can go from there to other pages and do other kinds of awesome things so find the navigation video right here or you can go to the playlist which is right here and of course you want to check if you're subscribed for the next videos that are landing right here see you for the next one [Music]
Info
Channel: Gerald Versluis
Views: 29,238
Rating: undefined out of 5
Keywords: .net maui, dotnet maui, .net 6, .net 6 maui, dotnet maui tutorial, .net 6 xamarin, dotnet maui getting started, .NET MAUI crash course, .NET MAUI workshop, dotnet maui workshop, dotnet maui full course, .net maui full course, learn .net maui, learn dotnet maui, net maui, crash course, .net maui tutorial, c# maui, what is .net maui, VS2022, mvvm tutorial for beginners, .NET MAUI MVVM, dotnet maui mvvm, maui databinding, xaml data binding, .net maui dependency injection
Id: XmdBXuNPShs
Channel Id: undefined
Length: 48min 33sec (2913 seconds)
Published: Tue May 17 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.