No More Magic String Navigation in .NET MAUI Shell with this Plugin!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
If you've been working with Shell in .NET MAUI, then you probably know that it can be a bit of a pain to manage all the routes and stuff, but not anymore. With this plugin that uses source generators. Let's go check that out. For those of you who don't know what Shell is, you've probably already used it without you even knowing because it's part of the default templates in .NET MAUI. It is a concept that was already built during the Xamarin.Forms era, but now it's in .NET MAUI and it's kind of like your opinionated implementation on how navigation should work, how things show up in your menu structure inside of your application, top tabs, bottom tabs inside of your flyout menu, that kind of stuff. So it is really easy and really powerful stuff to get your app started with that. But if you've looked into it and used all the power that Shell has to offer, namely the URL type navigation that is built in, which is really cool, then you probably already know that the URLs are kind of like magic strings, right? And that's typically something that we want to avoid. So we can get around that by using the name of of the pages and register routes that way. But still, it feels kind of like not great. But now there is a plugin to make things a little bit better, at least in terms of managing your things. It uses source generators to generate the routes in a static class that you can use inside of your application to go to a certain page and whatnot. Let's just dive into the demo and show you what this is all about. So here we are in Visual Studio 2022. I'm going to show you this today on Windows and also running the Windows .NET MAUI client. But this lives in the .NET MAUI layer, the abstraction layer. So this works out of the box for all the platforms that are supported, iOS, Android, Windows, macOS. You don't need to do anything special. It will work on those platforms without needing to change a thing. So here, this is just a new .NET MAUI project. I can run this and you will see the new template that we introduced for net eight with the cool race car with the 8 on it, little Easter egg there, and the button that will increment whenever we click on it, right? So we've got all that now let me add a very simple page and show you the very basic mechanics of shell. Like I said, without you even knowing, you're probably already using it because you can see AppShell right in here, right? So that's there in the template. If I add a new page, right click on my project, add new item, I go to the. .NET MAUI pane here on the left and we see all the things specific to .NET MAUI. Let's do a content page and let's call this SomePage.xaml. Doesn't really matter. So we get a new page with XAML you can do it in code if that's what you want. Welcome to SomePage, right? Now we have this one and we can actually get here by now doing URL navigation. So go to some page. So to do that we can go back to our main page, go back to our code behind. So let's go to my Solution Explorer, MainPage code behind and instead of this button to increment it let's do some navigation here. So let's remove this code that's code and what I can do here now is say Shell.Current. So we have a current object that represents our shell of the application. Of course if you want to be a good citizen and use MVVM and view models then you probably want to make this into a service and inject that inside of your view model, right? So current GoToAsync and we got a couple of overloads here. But the most easy one is just specifying a string here that goes to some page. You can also do like the URL with slash and dot dot slash and that kind of stuff. But you can also do in the simplest form same page, some page, excuse me. And now it will go to some page. Well actually I need to register the route first so this won't work just yet. So go to my Solution Explorer again, you can register the routes anywhere but kind of like your typical place to do it would be in the AppShell. So here we can have the AppShell and we can say routes... Actually it is Routing.RegisterRoute and we can say SomePage and we can say typeof(SomePage). So now it knows like hey we have this SomePage route and then whenever we see that route, whenever someone navigates to it, we need to get that some page out of our code base and that will be used to navigate to and then this of course this key has to correspond with whatever we navigate to here, right? So it doesn't really need to correspond to whatever that page is called but typically that is how you would do it. So if I run this now and we click the button then now it will go to this SomePage, right. We will see this new page coming up and it will go to the SomePage and I think there will automatically be a button to go back as well because this just uses a navigation page under the hood basically. So if I do this, you can see welcome to some page. And here I have this button to go back. So now I can go back and forth. So now we have this URL type navigation. But you probably already also mentioned, hmm Gerald, this isn't really great. Like if I'm going to change something here with changing this register route to some page one, now it's not picked up here with this SomePage, GoToAsync. And now suddenly things are broken because if it can't find it then it's not going to do anything, right. It's maybe going to give something in my output like hey, I cannot find this route but otherwise nothing will happen. So that's not great. Now what you could do obviously to make this already a little bit better is if you want to keep the same name for your page and the routes anyway, then you can say, hey, I want to use name of some page. And now we're good, right? Whenever something changes, this will automatically be picked up and everything will fall back in line or at least it will break at compile time and not runtime. So now everything will be all right again. We can do the same thing here, name of some page and boom, we're done. Right now it works again. But if you are going to use this in a more MVVM context, and you're really strict about not breaking the MVVM pattern, if you're now going to reference pages inside of your view models, that's a big no no, right? That's not something that you want to do. Look, it works again. So what you could do is kind of like place all your routes inside of a static class and reference things from there. Use magic strings or the names of whatever you want to do there. But still, that not feels great because you have to maintain that yourself. And that's kind of like where source generators come in. So my good friend Julian has created this cool package that will generate this for you automatically. So let's see how that works. I actually already installed it on my project right here. But let me just show you real quickly, right? Click on your project Manage NuGet Packages and you want to search for epj.RouteGenerator. Actually I have it here in my history probably. Oh, there it already was. See he has a couple of other plugins so definitely go check that out as well. But here he has the RouteGenerator. Make sure that you have the include pre release checkbox on for the time being at least, because it's only in pre-release right now. And this automatically generates root names for navigation based on a class name convention for .NET MAUI applications. So I already installed it else install it and it will do that for you automatically. All the things that are needed. Then what you want to do is go over to your MauiProgram and we need to add a little attribute here. So what you need to do here is do [AutoRoutes]. You can already see it and then we can specify a suffix. So now we do Page and with this we kind of configure that everything, all the pages that end with page inside of our project will get a root generated. So I think whenever I start building this, actually maybe it does it without building. If I go to dependencies here and then windows and analyzers, you can already see a note with the name of this plugin. That's how source generators work. You can see the code that is generated in here and we can inspect what is going on. So we have this one analyzer here and you can see it does Routes.g.cs. The g is for generated. So we have this and you can already see it picked up on main page and some page. So it created that for me. This const string main page. It does work with magic strings but that now matters less because when something gets renamed, this entry goes away for the main page and we have breaking changes because we are referencing that main page, right. So that's something that will be picked up automatically now still and this is done automatically so we don't need to maintain that ourselves. We also get a public property for all routes. So you can get a list of all the routes that are in here. It's probably something that will come in useful at some point. So what we can do now we have this auto routes page and what we can do now we still have to register it. I think there will be a nice opportunity here for also to the source generator to register routes from that same plugin. That will be super cool that you don't need to maintain this yourself as well. And what we can do now is here say routes some page you can see that we have intellisense everything main page some page all the things are here and you can just reference that from this thing right here. So we can do that and the same thing on like the navigation side. So here we can do routes SomePage, right. And if I go back in now, it won't be a surprise that it still works, right? Because this ties everything together and we can navigate from one to the other. Whenever something changes, whenever I'm going to rename the SomePage now, this will suddenly generate something else. Our source generator will do some page something and it will break our build at compile time. And you know, something's up. I need to fix something. So that is really powerful stuff. Now, one more thing, what you want to do, like now you probably have some page at some point. That's always how it happens. That is the exception to the suffix thing. So you don't want to name something page because you want to do this dashboard. We're going to add a new item which is going to be called dashboard. So let's do Dashboard.xaml, right? So we get that in there and now nothing gets generated because it doesn't have that page suffix. So let's change this text right here to something important. Did you subscribe? Subscribe to my channel yet? Maybe that's something YouTube channel like and subscribe down below. So there's this new cool YouTube feature where I say subscribe down below that, the subscribe button lights up. Does it do that for you? Let me know down in the comments. That will be super cool. So did you subscribe to my channel yet? Maybe that's something that you want to do. But now we have this dashboard and what you can do is go back to the MauiProgram and we have this extra attribute with the extra, was it extra, ExtraRoute? See, there it is. And now we can just register something that we want to do in here. So we have this dashboard right here. Of course, this kind of like breaks whatever we are trying to do here, because now we are specifying this dashboard thing as a thing and we are kind of like moving this magic string from here to another place, but it's still nicer than having to maintain that yourself. And it's probably not going to be renamed at some point anyway. So now what we can do is also have this route. So we have this dashboard right here. So that's there, and we want to, of course, do this dashboard. And we can now navigate to the dashboard from here as well, just to show you that it works and to give you one more reminder that you want to probably subscribe to my channel. So this is how you can use this cool plugin to make the routes management basically of your .NET MAUI Shell application so much easier. This seems pretty useful, right? No more manual management of all the shell routes right there. It feels a little bit cleaner, although it's kind of like still the same thing, but managed for you at least, and it will be generated automatically. And everything that's generated by a computer will be much less prone to errors than when you're doing something yourself, right? So that's a big win. And the less I have to type myself, the happier a developer I am. Julian, thank you so much for creating another wonderful package to enrich our .NET MAUI ecosystem. The community loves you, or at least I do. And Julian also writes a lot of wonderful blog posts, including one about this great package. You can find it down in the comments below, so make sure to check that out. And I have some thoughts about this packages. Like it would be super cool to also have the route registration through this package, right? So that you don't have to worry about that as well. And that goes automatically. So we'll see what the future of this package brings. Let me know your thoughts down in the comments below. And I'll be seeing you for my next video, which might be this one. See you for the next one.
Info
Channel: Gerald Versluis
Views: 5,479
Rating: undefined out of 5
Keywords: epj.RouteGenerator, .NET MAUI, dotnet maui, maui shell, shell url navigation, shell registerroute, .net maui shell, source generator c#, dotnet source generator, dotnet maui tutorial, shell register, dotnet maui app, dotnet maui mvvm, shell navigation task, .net maui, maui navigation, .net maui plugin
Id: XNLKyEPWqws
Channel Id: undefined
Length: 12min 43sec (763 seconds)
Published: Tue Dec 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.