Monday 21 October 2024

.NET Community Toolkit

>> On today's Visual Studio Toolbox, James is going to show us how to write less boilerplate code in our MVVM apps. [MUSIC] >> Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green. On today's show, my good friend, James Montemagno is joining us to talk about the.NET Community Toolkit. Hey, James. >> Hey, Robert. How are you? >> Good. Welcome on to the show. Welcome back to the show. >> I know, it's an honor and a privilege. It has been a long time since we've been together back in my Xamarin days, and we can start that off. >> Yeah, then you had your own show. >> Now I have a another one though. They keep giving them to me. Now I have this on.NET over on the.NET YouTube and on the docs page of course, where we talk about all.NET stuff, which is really fun. >> Yeah. We were at a conference, the DEVIntersection Conference down in wonderful Las Vegas a couple weeks ago. You showed the demos that you're going to show today. I was so blown away. I said, you got to come on Toolbox and show these. I know you did in on.NET episode on the Community Toolkit, We'll have links to that but I really wanted to focus on the stuff in there that is just super cool for MVVM developers. I was just blown away at how much code I now don't have to write thanks to this wonderful creation. >> Yeah. This is really fun because you actually attended my Don in MAUI workshop, which is really fun, and we'll put a link to that in the show notes. Through that, I talk about a lot of how to get up and running with any XAML based application and MVVM model, View Model. Then we specifically do in.MAUI app. But what I was telling you was that, hey, the stuff that I'm teaching actually applies to any XAML based MVVM application and you're like, oh really what about WPF and framework and core and that's I said all of them. I think in the world of MVVM, I'm big MVVM person, a big XAML person, I've done all the frameworks, all the UI stuff over the years and I focus a lot on, client development for iOS, Android, Mac and Windows cross-platform stuff was Xamarin and now.MAUI. For me, there are amazing libraries and frameworks out there that introduce, let's say like architecture best patterns. You have like prism, and things like this that are really lovely libraries or MVVM light and these are a little bit more opinionated. I myself, I always wanted just a little helper libraries that would not give me a full architecture pattern. Let me decide, but give me the things that I don't want to write, like Commands and different observable collection stuff. I had a library MVVM helpers for a long time that did this. Then I stumbled upon the.NET Community Toolkit, which was an evolution of the Windows Community Toolkit, which came from the WPA committee, get all the things right. I had Sergio on one of the maintainers of this, and there's actually a whole organization on GitHub called Community Toolkit. GitHub.com slash Community Toolkit and there's tons of them. There's one for Windows, one for Don and MAUI and one specifically for.NET, which is just generic that you can use in any application that's.NET based and introduces all stuff. This one specifically is the MVVM Community Toolkit, which is really cool. I'm not even going to show any Don Maui code, I'm just going to show actually some WPF code. But I think what's really cool about this is it's all the things that I wanted, which was MVVM helpers that was really optimized code that didn't have any framework that I needed to change the fundamentals of my application. >> Yeah. I think and we'll see this later on, but one of the cool things about using this toolkit and we're going to see that it uses source generators to write a lot of the code for you. What I would wind up doing is I'd go look at one of your sample applications and I'd say, oh, his base View Model, yeah, I'm going to start using that and then I'd use that forever. I don't know if you invented new things in it or other people invented new things in it, but that then became my standard boilerplate code until the next time I saw you do a demo app and you changed it. This way, you've got not just leveraging from one person, but you've got this community building this thing, and then every time you use it, you're going to get the up-to-date latest and greatest and whatever's in there. Not only do you not have to write code, but you're ensured that the code that you're not writing is the latest and greatest. >> Oh, well, do you want to see it? Do you want to get into it? >> Yeah, absolutely. >> Cool. Let's go out and bring out my screen. Yeah. This is the GitHub page that's actually part of the Dana Foundation, which is really cool. Lots of people working on it inside of Microsoft and outside of Microsoft too. You can see here there's all stuff. There's the.NET 1, the Windows, the MAUI 1, and a bunch of other libraries that are really great. I'm going to start off here first with a WPF app. Look at this. This is my beautiful, look at it. It's beautiful. >> Mm hmm. >> But check this out. It's all set up so if I type in James Montemagno, boom, it really does stuff. If I click then submit it submitted to the back end and it clears it off. This is standard MVVM and we've got data binding here, and we got an I Command. Beautiful. >> Mm hmm. >> Nothing special there. Let's look at the code here. Here, it is inside a Visual Studio. I'm in 2022, but this is preview, but standard will work as well. This is a WPF app. It is.NET 6. However, this does a work with.NET framework applications. If you're using.NET standard libraries to share your view models works with when you UI, UWP Xamarin forms, .MAUI all the things that I'm going to show today. This is very simple and some people are like, don't do a data context there, but I'm doing it. Very simple, just standard data binding. We have a first name property, a last name property, a full name property and a ''Submit'' Command. >> Okay. >> I have a View Model. This code will look very familiar to many MVVM developers. I have an I notify property change if I scroll the bottom down here, I have a very simple implementation of it. >> Yeah. >> Maybe not the best and then I have my own I command implementation that is totally not good because I stole that off of Stack Overflow from 100 years ago and it's just in here. Then we have things like this, which is a bunch of getters and setters, and here I have my first name. I raised my property changed. I also changed the full name, property changed, last name. Here's my full name here that just concatenates those two together and I have my beautiful I command that literally submits and clears out the first name last name, so boom, MVVM. >> Beautiful, it's like a classic definition of boilerplate code in there. >> Now, now many people will say like, "Oh, I have a base view model, I'm using other helper libraries." Totally understandable in general. Even when I do that, some of this code still ends up looking like this where I have set property and it's still multiple lines of code inside of here. What we want to do is get rid of all of this code and really get really optimized, really tight code. What we're going to do is we're going to bring in this library. I've already added it here to the CommunityToolkit.Mvvm. >> You just got it off of NuGet, right? >> Just off of NuGet. I just went into NuGet, bum, right here, bum. That's it. >> Okay. >> Right now, as of this recording, this is Version 8.0, it's in Preview 3 today, so you'll definitely want to grab whatever the preview is. Make sure you check that checkbox, this source code will be available so you can grab it, run it locally on your machine. The team is still updating documentation, so the best way to do it is go to the GitHub page and browse through samples for all the stuff, but they're also putting out blogs as well, and I'll give you-all those too. Here's what we do, we add that one single NuGet, nothing special. Now, what I'm going to do is I'm going to just delete a bunch of code, Robert. I'm just going to delete all this code. I'm going to delete all of it, so deleting all code, so much code. Look at all the code, just deleting all of it. Right now, it's all mad. It's like super mad, there used to be 100 lines of code, now there's like 30. I'm going to get rid of all these. Robert, I don't want any of it. >> Yeah. >> I don't want any of it, done. In fact, let's get rid of this thing. I can fit it all on one page, Robert. >> Nice. >> That's what I want. Now, nothing works. Let's do this. Using CommunityToolkit.Mvvm. I'm also going to be using CommunityToolkit.Mvvm.Input. I also want to do that in ComponentModel. Those are the two name spaces and there's a bunch in here that we're not get into, like validation, there's all this other stuff. Sergio and I went through that, so definitely check that out. Here's the first thing that I can do, is I can come in and I'm going to add an attribute. Instead of inheriting from INotifyPropertyChange, I'm going to go in and I'm going to add this attribute. This comes from the CommunityToolkit.Mvvm.ComponentModel. When I do that, few things are going to happen. First, it's going to tell me, this is really cool, it says, "Hey, you're missing a partial modifier." I'm like, "Oh, it's okay, let's do that." We're going to say partial. Now, if I actually came in and I said public main view model, we would notice that all of a sudden there's new things in this, like OnProperty or SetPropery. Where did those come from, Robert? They're not in my source code, but where did they come from? >> They're probably in the partial class, but you haven't written that partial class, have you? >> I have not. In fact, as you mentioned earlier, these are source generators that is using this. Where do we find that? I'm glad that you asked, Robert, because they're hidden over here under Analyzers. Here's the community toolkit, source generators, and specifically, here's all of them that are in there. There's one for ICommand, Messenger, Nullability, Observable Object, Observable Property, bunch of stuff. If I go ahead and expand this, here's the partial class. Now, this is code. >> So that code's already been written? >> It's all been written. It was generated. >> It was generated, and it doesn't generate at build, it generates real time. >> Real time. I didn't do anything at all. It's all right here. This is cool. This gives you every single thing that you need in here. Now you would never touch this code, ever. Like, is this is generated, it tells you, don't do it, don't change it, but this is giving me things. >> You can look at it to understand what's going on and confirm that it's doing what you want it to do. >> Exactly. The things that are in here, these are just nice helpers. Here, we can tell that it's using equality compares. It's actually setting property changes, it's doing all the nice stuff that we want it to do, so it's figuring out all that hardness for us automatically, which is beautiful. Now, that's nice if you are using it where you can't inherit from another class. Maybe you had a base view model and you couldn't inherit from something else. Now, built into this is also something called an ObservableObject, and an ObservableObject actually has the base class of all that stuff that you would need all ahead of time. You can add that attribute or you can do ObservableObject which implements INotifyPropertyChanged and INotifyPropertyChanging. This is actually like really, really nice. Now we're not using source generators, but this gives you flexibility. You can inherit from the class or you can go ahead and add the attribute which will source generate. >> Okay. >> Now, you can tell things are upset. Things are mad. First name doesn't exist. Last name doesn't exist, anything like that, so we want to light that puppy up. What we're going do is we're going to add another attribute which is ObservableProperty onto this. Now notice first name, it exists somewhere, Robert. >> Wow. >> Yeah, because now it's very happy. That is there and that is because now, if we come over here, what we should see ideally is boom, our source generator of ObservableProperty is lit up and we're going to see that automatically. Look at this, this has been generated for us automagically, 100 percent. >> You've created a string in lowercase and it created a property in uppercase, literally? >> That is correct. Now, this is very, very smart. It has some things, so that if you did underscore, for example, it would generate the same code over here. See, look it right there. >> Yeah. >> Smart. >> Stunning. >> The team has went through and they said, what are common naming conventions that developers are using like m underscore underscore this and that? They figure that all out for you automatically. >> Nice. >> Now, some other cool things in here is that this looks really long. This OnPropertyChanging, OnChange, blah, blah, blah, blah. That is because the team actually optimizes by caching the property changed events. It's actually a really optimized code. Normally, you would create a new PropertyChanged event over and over and over again. They've optimized. That's why I like this, someone really smart figured out all this stuff and I just add one line of code, Robert, that's all I got to do. That's super cool. Now we got a first name, last name inside of here. Now, that's pretty rad, but if we run this, this is never going to update because we're never telling the full name to change. Remember, we set to call that manually. >> Yeah. >> Inside of here, there's other things that we can add. Let me zoom in. If I do Also, we can do AlsoBroadcastChange, NotifyCan, ExcecuteFor, so if we're having ICommands you can also do that and I love it they give you this huge sample that you can just see here. There's also AlsoNotifyChangeFor. That one we can say, "Hey also, do name of full name." Whenever we change this, also call on property change for this. Now, of course, you can line those up however you want. If you want one line, you a multiple line, and what you want. Now, we go back in that source generated code. Notice this file is open. It's just updates. Notice here that it's going to not only call changing for first name, but also full name, too. >> Very cool. Very cool. >> Now, you're probably saying, well, cool, we got that working. What about I commands? >> What about I commands? >> What if I just did, I command? Now, we're done? >> No way. >> Yeah, that's true. This is just about the coolest thing I've seen all year. Now, I can open up the source generator for this. >> All of last year too. >> Yeah. Low and behold, what we'll see is that they've generated tons of optimized code. They have their own relay command, and this will automatically On-Demand create the relay command for me, call the summit. All that stuff are good to go. Now, what you're probably saying, Robert, is, what if I have an asynchronous task in easing command? I'll just do ''Async task''. Save on there. Let's go back over here and let's see what our code looks like over here. Let's have it regenerate for us here. Async task. We've got to bring in the namespace. That'll work. I'm going to go and open up that ''Submit'' again. Now, check this out. I async relay command. Done. >> Beautiful. >> Now, Robert, you're probably saying, James. What if you have parameters? Sure. Let's do a string of name. Let's go in the generator code. Oh. Look at that. >> Unbelievable. >> Now you're saying, okay, it's generated submit commands, so it appends commands on the end. What if you did like submit async? What if you changed your name here? What if this was async, for example? >> Yeah. >> Well, it's generated a new file, so let's go over here. But it's generated submit async for us. >> Yeah. >> But here's the thing. It is calling submit async, but they still called it submit command. Because you don't want to be submit async command, doesn't make any sense. They chop off the async, but they're smart enough to know to call that for you automatically. >> Okay. >> That's all you need to do. Which is really, really neat. Now, if we just, like, let's move this back to the void, let's mimic here. We're going to get rid of our stuff. Right now, we're back to our old stuff over here. I'm just going to hit ''Run''. >> Does generated async file go away? >> Yeah. That one now the submit async went away, now it's just submit and it's generated a new code for us. Now, we're going to go ahead and we have our app running over here. Let me zoom in. There you go. Sure enough, I do. James Monte Mag now hit ''Submit''. >> That is so amazingly cool. >> Yeah. Now, like I said, this code that I have here is really going to fit just about on one line. We went from almost 100 lines of code. Our own implementation down to, honestly, this right here is just, 16, 17 lines of code. >> Well, you don't have to write this plumbing code anymore. I notify property changed. You obviously want commands. Why do you have to? Why can't you just attribute it, just hook it up? Why do you have to go and learn that code in the first place and then use some implementation that you may have found to basically do plumbing code? We're supposed to be focusing on the UI and the business logic and the whole purpose of the app. >> Yeah. I agree 100 percent. In the workshops, I actually have the workshop on me put up here inside the dynamic workshop, inside of this NVM, it's really quite fun because I have you write all of the plumbing code and then delete all of the plumbing code. >> Which is actually good, because it's good to learn what's happening. >> Exactly. >> It's good to not have to write it ever again. >> But to me, this is beautiful, and this is all I ever want to do. To me, this is the way of creating this. Now, that being said, the only thing with this generated code, is I think it does use C-sharp eight features. I do get this question a lot, which is I'm inside of a.NET it framework app, and it actually gives an error. It says you need to update that. Now, I'm here inside of a.NET six apps. There's going to be using C-sharp 10. You can always come in and say lang version. You can say 10.0 or you can say latest, and remember that these features of C-sharp, most of them are compiler features. The team that does the.NET community tool kit, they said, what's the maximum way of making sure that the code that they're generating is new and modern but offers the best backwards compatibility? You in a.NET framework app, you can use C-sharp 10. There's nothing stopping you from using it. Of course, there are going to be runtime features you can't use. But as far as the code, for example, this little question mark, question mark equals over here, this is a C-sharp 7 or 8 feature, you can just flip that on you'll be good to go. It's going to cause no errors at all because it's a compiler. You can compile it. >> Yeah. As long as you're targeting the right framework. >> Yeah. I mean, if you're in a.NET framework inside this repo, let me open this up. For example, I have another.NET, a WPF app. This is a framework app. The same application inside of here. I thought it was a little bit prettier. But if I actually go in and I say, unload this thing, look at this, 472. There's a big one in here, blah, blah, blah, blah. Now, in this instance, I'm using the old style as the case, that old style stuff. What I did, is I put this code into.NET Standard library, or you could put it into like a just standard class library there. This will totally work. You can see the same exact code till I get to go and, yeah, that'll work. I just flip on the language version and you're off to the race. >> Then your generated code is in that shared library. >> Exactly. Yeah. That means it's going to be nice and testable in general. Yeah. That's it. >> That is so fantastic. >> It truly is. That's all I got. That's all I got, Robert. >> That is just so cool. We will include links or even go get this and learn about it. Also, put up a link to the longer on.NET episode where you talk about additional things. But if you're doing mVM, you should just start using this immediately. >> Pretty much, yeah. Huge shout out to Sergio and the team. >> Yeah. >> They use this in production, in the Microsoft Windows Store itself is in there. It's like being used in production is cool. Sergio talks all about that and all the other features too. Definitely check out everything. All I did was use it and talk about it. I had nothing to do with their creation. Shout out to the team that actually builds the stuff. >> Well, thanks so much for coming on the show. This was awesome, and I hope you guys enjoyed that. We'll see you next time on Visual Studio Toolbox. [MUSIC]

No comments:

Post a Comment

ASP.NET Core 2.2

hi my name is Glenn Condren I'm a program manager on the asp.net team and today we're going to talk about some of the ...