Transcript for:
Exploring .NET Aspire for Application Development

I'm going to do something a little bit different today. I was recently doing an introduction to.NET Aspire talk at a local user group over in Portland, and I thought to myself, wow, I should have totally been recording this. This is a really awesome session.

So that's what I'm doing today. I'm doing presentation style, James. Doesn't happen that often, but full end to end of everything that you need to know about building better apps with.NET Aspire. So if you're brand new, you've been using.NET Aspire a little bit and want to see what else you can do, that's what you're going to learn today.

I'm going to go through a whole bunch of different demos from... getting started to full publishing with.NET Aspire that you can add to your applications today and make them better. So let's go ahead and get into it.

So you've clicked on this video and you're like, wow, what is.NET Aspire and why and how can I build better applications with.NET? Well, it's a great question. That's what we're going to talk about today. Because when I got started building applications with.NET and C-sharp, I never would have imagined the amazing different platforms and technologies that I could integrate in from a single platform in single language. I started my journey building desktop Windows applications.

I went on to build backend services, games, mobile applications, and infusing them with AI. And that's the cool part about.NET. Because here we have a single platform to build for any single type of application out there. World-class developer tools.

building across different operating systems and amazing ecosystem that's out there. Now, while I started my journey building really desktop and mobile applications, at this point, my applications have incorporated all of these together, right? When we think about it, our applications don't just stand alone. We have backend services, frontend applications, authentication services, databases, different integrations all across the place, which is something that we sometimes don't think about when we're creating a new project.

But as we start to build our application integrate with our different services across our company our applications start to grow and as our applications start to grow our applications need certain things no matter what type of application we're building in fact every application needs to be observable resilient scalable and manageable what does that actually mean well observable is kind of hopefully a little bit obviously i want to see inside what's happening inside my application i want to be able to get that log and that telemetry of what's happening in my app to help me diagnose problems When it comes to resiliency, I'm a mobile app developer, so I understand when we don't have great internet access, for example, and things can be a little bit flaky, or maybe a database goes down or a service goes out. It needs to be resilient. As our applications are growing, whether it's one user or one in a million users, we need to be able to scale it up and scale it down all the way to zero. And of course, we want it to be super manageable, easy to get up, to get down, and easily to scaffold out our architecture and add more services in.

So now we think about this, we say, okay, well, how do I get all of this stuff? Well, there's actually tons of things built directly into.NET. And actually in.NET 8, this is right from the.NET Conf slide deck, I'm pretty sure, is that the team built all sorts of new things to incorporate observability, resiliency, scalability, and manageability into.NET applications.

Now, this is just what's new in.NET 8. There's, of course, tons of things built in to.NET itself. But we can see here, we are... better integration for metricing and redaction and better logging support testing for logging and metrics and fakes new poly based resiliency packages you know stateful reconnect for signal r for example and tons of great performance and aot performance improvements and integrating in the latest container technology with chiseled ubuntu container images which is really awesome to see so this is all awesome and you're saying to yourself well james don't get all that stuff that you just talked about well It's still a little bit complicated, to be honest with you.

There's a lot of different choices out there. It's not necessarily easy to get started. It's not necessarily a paved path.

And things, again, can be a little bit complex. They're saying, well, James, you just talked about all those amazing things that are built in. Well, yeah, some of those things are on by default, but a lot of those things you got to go turn on yourself.

You got to integrate and test into your platform. And in fact, there's a lot of choices out there. You know, if you look at the CNCF, for example, the native landscape that's out there, there's.

hundreds upon hundreds of different choices for the different parts of your application that you might want to integrate into your app. Whether it be from Cloud-native storage or runtime, different platforms, CI, CD, imaging building, streaming and messaging, databases, observability analysis, there is just so much that you could choose from when it comes to start building applications. Now, while this is from the Cloud-native compute foundation, this really does apply to any application. whether it's one or two services or a hundred services out there, right? So how do we as developers get access and get rid of all that complexity and all of those choices?

Well, that's where.NET Aspire comes in. It's a cloud-ready stack for building observable, production-ready, distributed applications. And a distributed application is any application that you seek to distribute anywhere out into the world.

So really building better apps, no matter what you're building. Now, you might be saying to yourself, what is that? actually mean, right?

Who is it for? Who should use it? And it's a really great question. I like to say that.NET Aspire itself scales for all types of applications and it can grow with you.

And we're going to talk about that today. So let's say that you were building, I don't know, like a commerce website. Maybe you were selling some sort of fitness gear, right? For example, this is the eShop sample that is actually a great.NET Aspire sample that's out into the world. You have a shopping cart, you have a login page, you have some products here, and you might just be starting to build this application.

You might say to yourself, well, you know, what would that sort of of architecture look like. If you're getting started, you might just start with a front end, maybe it's a mobile app, maybe it's a Blazor web application, and you might just have a data source. Maybe if you're prototyping, you might actually just start with a JSON hard-coded string, right, and a bunch of images that you're shoving into your application, because you want to prototype and get out faster.

Now, the cool part here is that even if you're in this stage of development, what I'm going to show you today is how.NET Aspire gives you better insight and helps you get rid of a bunch of developer toil that's out there, the things that bug us today when we're developing any application in any programming language. We're going to see how even if you're just prototyping your application, how.NET Aspire is awesome for that scenario. Now, as your application grows, of course, so does the complexity.

You might integrate that web front-end with API services, with different databases, you might break them into multiple microservices and.NET Aspire really starts to shine at this point. Of course, you might be going big, big, big architecture, like the eShop sample that I just talked about, which is all microservice and cloud native technologies and integrating in AI, of course, and observability and event busing and different types of caching and databases and has mobile apps and has reverse proxies and all this goodness. And this is really, really, really where.NET Aspire will shine, but it'll shine throughout all of these different scenarios that we're going to talk about today. Okay, so let's get into it because.NET Aspire is truly your building blocks for building cloud native apps, distributed applications, or any applications.

And it has a bunch of different components that really help developers be more productive and makes apps better. It gives you a bunch of smart defaults that automatically turn on a bunch of that goodness, such as health checks and resiliency and observability into any of your applications. It gives you a developer dashboard to get insight into your application for all that telemetry. It can orchestrate. a bunch of your different projects together and load them up and start them up from a single project so you can just boot them all up you can also integrate service discovery so your back end can tell the front end hey i'm going to use this and the front end can discover it through a simple key based system and that extends to different integrations and when we say integrations these are different sort of libraries out there like postgres and sql and messaging and open ai for example and all sorts of different things that you're integrating into your application.

The integrations will not only opt in to some things like health checks and telemetry automatically, but it will also be orchestrated and it'll opt into service discovery, really simplifying application development. Then we'll talk about deployment. Deployment is really unique and.NET Aspire can help definitely get your app up and running very quickly, but it integrates into a bigger ecosystem so you can continue to deploy your applications exactly how you are today or you can use new tooling to deploy them in new interesting ways.

And that's what we're going to talk about. But first, we're going to talk about specifically those first five building blocks. That's right. We're going to leave deployment to the end, and you'll see why. Because I want to do a deeper dive into deployment and how it actually works under the hood.

So let's go ahead and get into it and add.NET Aspire to our very first application. Hey, friends, before we get to the code, let's thank our... good sponsors of this video, Hobby Nerd Studios and DinoGod, and their brand new board game, Age of Angra, is a highly technical tag team fighting card battler.

This game is absolutely fantastic. It's by one of my best friends in the entire world, Ben Rees, who was the officiant at my wedding, who worked with me on Shred Nebula at Crunch Time Games. Now, I could tell you all about this game and how I love it. It's sort of like a modern day Pokemon mixed with Street Fighter in card battler form. Let's go ahead and have Ben tell it how it is.

Age of Angra is a 2v2 monster battler in which the player will build a team that consists of their two monsters and they will also pick a mechanical identity in the form of a shepherd which also has its own cool abilities that influences the team in specific ways entirely skill-based no chance mechanics has a good depth and width to it and allows the player to not just express themselves mechanically but also thematically there's a good selection of of creatures to pick from there's a good selection of shepherds it's it's an environment rich with synergies there's all kinds of fun combinations of monsters and shepherds i would say feels like a slow motion fighting game in all of the depth that that means. Pick up a copy of Age of Angra today. If you love highly technical board games, there's a link in the description below where you can pick it up. Now let's get back to the code.

All right, let's get right into it. So this is my tiny shop application. It's a simple application, but an application that I would build, which consists of two different projects.

I have a products project here, which has a bunch of endpoints for me to get a bunch of outdoor sporting goods. So I have product to get all of them here. I'm getting the ID, a put a post.

It's normal rest stuff, right? It's anything like that. So that's what's inside of here.

And I just have a simple data context, just normal entity framework type of stuff here. That's going on. And I'm just seeding the data with some hard-coded things here, which is great. Now over in my store, this is a Blazor application.

So I have some components. I have some pages over here. I have all sorts of good stuff going on. If I look at the page products over here, we can see that I go off. I have a bunch of products that I put into a grid, and then I'm able to initialize them here.

Okay. So the first thing that I want to talk about is some like a developer toil, some developer sort of things that sort of bug me a little bit sometimes. when i'm doing any source of different development is i have multiple projects here so if i just like run this products startup i'm just going to be running the back end here right so for example you know i just got an exception over here so we can take a look at that later and let's see if i refresh it again okay get my products back okay so that's good now i'm like let me run my front end well i'm debugging currently so i'd either have to open up another visual studio or run this one without debugging like what do i want to do here So normally what you have to do is if you're in VS code, set up a multi-project setup JSON file to launch both projects at once.

In Visual Studio, you can right-click on the solution, go to properties, and go to everyone's favorite dialogue, which is only stored on your local machine, which is the multi-project startups here. Here I can say, okay, products, let me start that up here both in debugging. So I'm going to start both of them in debugging, hit okay, and go.

All right, this is looking pretty good. So now we can see that this is using multiple startup project. Now, if I run this here, this is going to boot up my, uh, back end, my front end, and hopefully a bunch of windows. Okay, cool. Like I guess some exceptions.

All right. We'll come back to those in a bit. And here we have our, uh, here we have another tab over here. Let me just combine those tabs, I guess.

Let's see if I get my, uh, projects back. All right. This isn't running anymore.

What's going on. So I might try to figure out what's. going on here by, I don't know, opening up this project and say, okay, well, it looks like we have some diagnostics here. It looks like the debugging stopped. That's fascinating.

Let me go ahead and try to start it up again, right? So I would come in and I would start things up again. Okay, like what's going on? Hopefully I get my projects running again.

There we go. Go to my projects page. Okay, I have everything up and running. But a bunch of things are happening here, right? I have multiple different command windows opening here.

I'm getting different output requests over here. I have to parse all this different information, and then I need to open a bunch of different tabs. This is quite a lot going on.

That's the first thing here. We also saw that there's different exceptions. For example, let's say I was running this application, and instead of running both in debug, I ran the products without debugging. So I'm just trying to debug my front-end. Now, in this case, I might boot these up, start up this project, and now we're going to get a bunch of windows still opening up here.

But my main one, get my projects and I'm running this here. Now, what's fascinating is in this instance, since I'm not debugging the backend, we can see that nothing is happening here. So I assume an error must have occurred, but I can't see it. Right.

And in fact, if I look over here, I'd have to go parse the logs and see, yeah, okay, actually an exception did occur, but it was kind of silent to me. going on debugging this application because the exception happened in the backend and it just happened to not be debugging it. So you kind of have to have everything up and running and configured in this way, which kind of makes it complicated. So let's think about how we could, for example, make this a little bit smoother over here.

Okay. So the first thing I'm going to do is add.net aspire into this project. And there's a few ways of doing this. So if I want to, I can come in and I can say, add, And then I can say new project.

Now, you'd want to make sure that you have.NET Aspire installed. You get that through Visual Studio 2022 installer, but if you're also doing it from command line or VS Code, you can say.NET workload here. I'm going to say list. This is going to list all my workloads.

I'll make that a little bit smaller and a little bit bigger here. There we go. We see that we have the Aspire workload installed. Now, of course,.NET MAUI here as well. If you don't have it installed, you can say.NET work workload install and you can say.NET Aspire and that will go ahead and install it there for you automatically.

That's how you get it. Now, once you have it, there's a dropdown here or.NET new project and there's.NET Aspire. There's all sorts of things in here like test projects for integration tests, a full starter project that gives you backend and frontend and a bunch of things in there.

We're going to add it ourselves. We have an empty project, an app host, and a service defaults. So when we're adding.NET Aspire to our application, again, we're opting into these different areas. We're going to want to add service defaults, which give us this nice defaults for doing a bunch of goodies inside of our application like resiliency and health checks and a bunch more things, and also the outposts which will orchestrate it.

I could add both of these projects manually and then add a little bit of code to link them together, but I'm going to let Visual Studio do it for me automatically. I'm going to right-click, say, Add.NET Aspire Orchestrator Support. Now, this is going to show me.

It hasn't detected any other app posts, nothing's in here. It's going to create two projects, the app posts and the service defaults. I'm going to say, okay. It's going to do a few things.

Here we have the service defaults and we have the app post. The app post is going to be the new startup. You can see that Visual Studio actually switched the app post to be my startup project.

I don't have to worry about the multi-project startup things at all. Now I'm going to go and close a few windows over here. I want to show you what's going on and zoom in. First and foremost, if we go into the products, we're going to see what happened. First, under dependencies and projects, Visual Studio added the tiny shop.service defaults for me automatically, which is pretty awesome.

Then if I look at the tiny shop service defaults, we're going to see a few things inside of here. First, we have the service defaults themselves. These are things that are the best practices that every single project that's using.NET Aspire gets like open telemetry.

default health checks, service discovery, not only for the services, but also for the HTTP clients. And it also adds standard resiliency handlers automatically. And we'll see what that looks like.

Down here, these are the calls that it's doing. So it's highly customizable. So we get all of the open telemetry scopes and formatted messages. We get metrics, we get tracing.

Right now we're using HTTP client, but if we were using gRPC, we could turn that on. And it also automatically configures the open telemetry exporters. Right now, it's going to export it into the.NET Aspire dashboard that we're going to see, and that's what it sets up automatically. You can also go ahead and configure things like Azure Monitor.

If you're using Grafana and Prometheus, you can go ahead and configure that as well. As the beauty of OpenTelemetry, you can pipe that into a bunch of different exporters. Now, down here, what we're able to do also is configure the health checks.

Now, there are multiple types of health checks. The one that we're seeing here, is actually one that is just a self check. So this here is going to see is this specific service live for example. If we look below at the map default endpoints we're going to see that we get two.

We get a health and we get a live. And we're going to talk about these health checks as we start to add more things into our project that's using.NET Aspire. Now this was automatically configured for me. So if I go to products and I go to the program CS we can see that Visual Studio added this line of code add service defaults that configures everything and it also automatically added this map default endpoints which are coming from our service defaults those are added for us automatically so that's really cool it just adds that automatically for us cool so let's say i just want to run this now i'm going to run the https and what we're going to get is what you would think is that same exact products json files that we saw earlier when we were running that right?

We just added that one project, but instead we get the.net aspire dashboard. You can go in and you can configure system or lighter dark mode, which is really nice. And what we get in here is resources.

So this is say there's a project that is named products. It's running. This is the source. And here are the endpoints, HTTP and HTTPS.

Now it knows that it has a single API project of product here in the, in the products project and i can go ahead and tap on one of those and now what we're going to see is i get that information back i can go ahead and refresh this and we of course do get an exception which is fascinating and we get that back and then we look again a few more exceptions as i refresh this here let's see if we can get one that doesn't give it as an exception that random really working for us that's for sure there we go and we're going to go and get that one more time we get it back perfect awesome so we get this information here but we also see that we can look at logs for example and this is pretty nice so we do get one window that popped up but this is actually starting the outpost and what it's doing is it's logging us in automatically to the dashboard so that's kind of nice and we can see the failures here that's really cool we can go into structured logs and we could actually look at everything that's happening over here so we could filter by log level errors warnings anything like this and this is actually a cool blazer application that's using fluent ui but what i want to point out here is that you can view details so i could say okay let me take a look at the details here here's the connection id the request what was going on i could really diagnose what's happening inside of here i could also take a look at a stack uh trace over here so the traces give me a timeline in history of what happened so this one's pretty straightforward but it's basically showing me that this got called the browser's requesting and i got an error so so that's just what it's going here because i only have one product and project orchestrated but i can even also see metrics So here automatically, like I didn't change anything into my application at all. I'm getting active requests, durations, routing, connections, all these things open telemetry for like how much assemblies and exception counts are occurring in my application. I can get different tables and graphs and I can get all this information and sort over time in real time to diagnose my app. So now you're saying, okay, like, well, where did this thing come from?

How did it know to start this? Okay, well, let's take a look back over into our app host inside of our app host. It's very, very simple.

Under dependencies, we can see projects and it has the products referenced. This is the orchestrator. So think of it as code as infrastructure for my application.

It is describing what is in my application and what the dependencies are and how they relate to each other. So here in the builder, it says add project and it says projects here.products. Now this here is being generated for us automatically.

with source generators when I added that project there for me, and it knows this automatically. So if I go around from your machine to my machine to anyone's machine, this is going to be generated every single time I open it up. So it knows how to start it up. So that's how I get that metadata.

Then I'm giving it this key over here. And this key is what was identified in the dashboard, but we'll see how that comes into play as well. Okay. So let's say now at this point, we want to add other projects.

So how do we get more in there? Well, we could, for example, go ahead and drag and drop the store onto the outpost and then configure it up. But I can also right-click, add, and then I can say.NET Aspire Orchestrator support. Now here it says, hey, I don't need to find another outpost or service defaults.

You already have them, so let's go ahead and integrate it there. We can see that the store popped up right there inside of our application and we can see that the Program CS was automatically updated right here with another project. Now we have projects.store and it's opening up and it's good to go.

If we go into that code, into the program CS, we can see sure enough, add service defaults were automatically configured. Then down over here, we can see that the map default endpoints are there. So we get that all up and running.

So now I can go and start up the application again. We get one pop-up which is running again, the outpost, the distributed application. Now we get the dashboard again. But in this case, we get two projects running. products and store now this time if i tap over here on my products we can see sure enough they load up automatically i can refresh i get an exception now i'm getting this exception by the way uh because uh in this case maybe we can just say uh let's not break it anymore and let's go ahead and continue on i have a little randomizer in here so if we look at the code this is just randomly throws errors here but But what you may notice is that this is actually taking a lot longer in this case, it actually failed again.

But if I refresh it and refresh it again, and we might see that different refreshes are giving us a different sort of loading experiences here and what's happening. And now we get a success is that this is part of the standard resiliency. We come back into our resources. We can take a look at those traces and now we can see exactly what's happening in the application. We can see, oh, actually.

The products this call here was successful. If I view that stack trace, we can see what's going on over here. Who's calling what the store, the get, the products are getting called and how long they're taking. If I come back into the traces again, we can see those errors.

So here, this one took five seconds. For example, I'm going to refresh that and we can see exactly what's happening, what's happening, who's getting called, where things are getting returned over here. So the store is doing get to the products and then this is failing back in the store and we can dive in deeper into those details automatically and see how long it took and why did that happen, right?

So if we go back into those service defaults that we opted into and scroll back up is because automatically the standard resiliency handler was added. Now, of course you can go ahead and automatically configure all of this like you would do. for normal resiliency. So if you want to control how many times it retries, how long it waits to retry and everything like that, you're able to do that automatically, which is super cool.

Now on top of that, if we come back into our application, we can see that I mentioned we also have slash health here, which is going to go ahead and call in and say that this application is healthy. That's good. And I can also say alive.

And now again, this is also healthy because this is this application. So I could use those health checks automatically. And those have now been integrated not only into the front end, but if I go over here into the back end, there we go.

Let's open that up. And I say slash health. There we go.

I get healthy as well. My back end and my front end are healthy and also alive. Now we'll come back to these health checks automatically.

But remember, because. Down in the bottom, we were enabling and mapping the defaults for health and alive. These defaults were automatically added for us.

And in this case, the self health check was added automatically for us. Now we'll come back and you can extend these. You can add your own health checks, whatever you want.

But we'll see as we start to build out our application, how this continues to add a lot of value into this app. Okay. Now, one thing that is happening here is I didn't change anything. really in my application, right?

Yes, you know, the map default endpoints and the service defaults got added. But we can see that right here, automatically, the product service, which is the HTTP client is using the product endpoints that are in here. So if I look at the app settings, we can see, oh, well, this is fascinating product endpoints are automatically configured here. So again, I didn't change anything, I could continue to deploy my application exactly how it is today with those exact endpoints.

So nothing else has happened. happening here. But one thing that is really unique is the ability to use service discovery.

So instead of having these hard coded strings with endpoints in here that might change here and there, or that, you know, a developer might have some port blocked inside of it, and you change 1000 places inside of it, we might want to use service discovery that uses unique IDs for discovery. So if we go back into our app host over here, I go into program CS, what I can do is I can assign this a variable. So I'm going to say API here. And we can see that add a project returns an I resource builder.

Now what's important about that is that if I come into my store, I can say dot, I can come in and I can say with, there's a bunch of different things in here, like annotations and args and endpoints, there's a whole bunch of things inside of here. But one that we can do is say with reference. What this allows us to do is reference other projects in our system. So here I can say API. Now, this is basically going to tell the.NET Aspire app host to configure the API products, to configure endpoints and environment variables that the service discovery can opt into.

That's what it's going to do here. And now we can use this key of products inside of our store. So we can do it in one of two ways.

The first thing is we can come into our actual app settings and we can say HTTP S plus HTTP colon products. And we can actually remove this here. We could have different endpoints if we want to, but the single endpoint HTTP S plus HTTP is saying Please try HTTPS first, then fall back to HTTP. We could also just say, hey, only use HTTPS here.

But Service Discovery can opt in and do these different endpoints here. Now, what that means is that at this point, automatically we're still going to pull from our product endpoint here that exact same thing here. Now, the nice thing is we could get rid of this completely. So I could come in and I could delete this.

I come into my program CS, and I could just say, yeah, var URL equals this right here. There we go. Now I could run the app host again, and at this point, My exact same application is now going to be using service discovery.

In this case here, let me go and open this up. There we go. When I open it up, I'm going to see that I have my tiny shop, my products that are loading. And sure enough, there are my products coming back. Now, how does this actually work?

Well, if we come into our details, I'm going to pull this up here. We can see that there are a bunch of different configurations in here. We can see that these are the endpoints of this project.

But if I scroll down, there are a bunch of environment variables configured for me, such as ASP.NET Core, the HTTPS port, the URLs, which are coming from my actual project, and then a bunch of other things like logging and open telemetry. If we scroll down to the bottom, we're going to see these two, services, products, HTTP 0, HTTPS 0. These are the local hosts that Service Discovery is using. for us automatically.

These were injected by the.NET Aspire app host based on the orchestration that we put in place. So that is really, really neat. So that means if we wanted to just simply deploy the same exact application to Azure or to some other cloud service or on-prem, we would just update our environment variable to be this specific name to fall in line with how exactly.NET Aspire is looking at.

These IDs in our project, which is really cool, which means then I could come back and close this down. I can just simply deploy my backend, deploy my front end, just like always, and use those specific environment variables, which is super duper cool. All right. So now we have our application.

We're in the same state and we've solved a lot of different developer toil, right? We got rid of that right click properties, this thing down here, no longer have to do that. We're.

orchestrating our application so multiple things get set up we have health checks we have resiliency we have our our service discovery automatically come set up for us and just a few lines of code in this distributed application and dot inspire gives us all of that and this beautiful developer dashboard to also help us diagnose different errors okay so let's say we wanted to build some things into this maybe we need a database maybe for example we need caching layer, maybe we need authentication, maybe we need some APIs or different things inside here. How do we get them? Well, say you did want to add Redis to there, maybe I want to add some cache here into the products APIs, or I want to cache the results every time, so I didn't hit a database, for example.

Well, how would we do that? Well, first and foremost, that is where the different integrations for.NET Aspire come in. If I right-click on the app host and I say, add.NET Aspire package, This is going to look for different tags and owners for.NET Aspire for these different integrations. There's two parts to integrations, one for the app post, which will allow it to understand how to configure it, and what is needed to boot things up, and then integrations into either the products or store different projects. I'm going to scroll here and we can see that we have Redis, SQL Server, Postgres.

We have Azure specific items on here for Service Bus. insights, cognitive services, Key Vault, Orleans, Azure SQL, MongoDB, Kafka, AppConfig, PostgreSQL. So we have all these different things in here from the team, but also there's tons from the community as well. But let me just go ahead and install the Aspire hosting Redis over here.

I'm going to install that first. Perfect. There we go.

If you've ever configured Redis, you know that it... Takes a little bit of time to figure out what containers I need to get. What's the official one?

How do I pull it down? Do I run it on my machine? What do I need to do?

Well, if I come over to the app host, I can create basically another resource. I'm going to say var cache. I'm going to say builder.add.

And we can see here that I can do a bunch of different things. Like I can go in and yeah, add a project, but I can also add a Docker file. I can add a container.

Maybe my products backend needs a container to be running, to be exposed. Or here I can add Redis. And here I'm going to go ahead and say, add Redis.

I'm going to give it a key of cache. There we go. And now I can say, just like I did before,.with reference cache, just like that. And now with this single line of code, it's going to know how to pull down the Redis cache container image, boot it up and start it automatically for me, and then, It's going to opt into service discovery here for the products, which is super duper cool. Now, one thing I like to also say is that I can add some other things in here.

So for example, Well, there are a bunch of other items in here. Like I can do all the different configurations. I can say, uh, with an image registry or an image tag, if you want a specific version or you want a different, uh, different Redis compatible container image. But I can also say with Redis commander, Redis commander is basically a user interface to inspect Redis.

And it's a separate container image. I can configure that as well. So I've done that here. Now let's go and add it into our APIs. I'm going to say products, and then I'm going to say add, and again, I'm going to say.NET Aspire package.

All this is doing is just simply searching automatically here for specific tags and owners. There's a bunch of community ones as well, obviously, which is great. You can add a bunch of things, you can create your own components.

All these are doing here, as we can see is we have RabbitMQ, we have. We have Postgres, we've gone for entity framework. We have storage blob output, caching, distributed, caching, cosmos table, sack, my sequel connectors, what the.net aspire team has done and what community members have done is they have for all intents and purposes taken the standard stack exchange, Redis output caching. And they have included, we can see here health checks, logging telemetry to help integrate with.net aspire.

so they add on top of it but what we can see is that it's just using standard stack exchange redis if we actually look at this one and we look at the the what it's using under the hood is stack exchange.redis so it handles all that for you automatically so let's install this one perfect just going to go ahead and add this in nice accept that and now we can do is we can go in to our products here and i'm going to go up and the first thing i'm going to do is i'm going to say builder.addRedisOutputCache. This is what.NET Aspire has added for me into that integration. It says, add Redis Output Cache, and this will configure everything for me automatically and opt into service discovery. Now, of course, I also still need to do just standard ASP.NET Core output caching. I'm going to say use output cache.

Now I'm just going to use standard API. So I'm going to go to product endpoints. And here I'm going to say, output cache, just like that.

And this is going to bring in, if I go ahead and add this in here, right-click, add in the standard Microsoft ASP.NET Core output caching. So we'll cache that single call that's coming in automatically for us. All right.

So there we go. Very, very simple, right? I added a package to the app post. which enable me to go ahead and get this up and running. Then over here in my program project for products, I have my program CS.

I simply said, hey, yeah, use the Redis output cache, and then go ahead and use output cache. Let's go ahead and run it. Now I want to bring up one other thing, which is my Docker desktop here.

What we want to see as this boots up, we're going to see that these two are starting. and that is because if we go ahead and put this over here as these boot up dotnet aspire app post when it boots up is looking to see what container images do i need and it will download them for me automatically you can use docker desktop or you can use podman and then it's going to start those up automatically so here we can see that it has the redis cache and the redis commander here for me as well which is super cool okay So now we can see that I have those up and running and go and click over here. And my application will of course now be running those products, pulling them back for me automatically or refresh ideally a little bit faster, hopefully. And if I come back in to my traces, what we should see is that, oh, there's actually errors that occurred. But if I look at this one, we can see this is cool, right?

We can actually see that the second time I refreshed it went in, it did a get. went to products and it returned from the cache so if i had a big database i was calling back to it would speed that up super duper fast we could also see where those errors were occurring that this went in it called it all back and it actually went through let me this is a little smaller here it did a get try to return it did the get and then the set so it automatically pulled back and stored that inside of the redis cache if i come in i could load up the cache commander over here And now we can take a look over here and we can actually add keys. We can look at everything that's happening. We could talk to the Redis, uh, uh, cash here automatically. We can see everything that's happening inside that container and when new items are being added or removed and we can see the connections being received automatically, which is really nice.

So we can diagnose this in further detail. But I want to point out that if I go into the console log, I can see, yeah, here's my cash log, right? All that is here for me. This is coming from that there.

I can look at my products here. There's the exception that occurred, right? I can look at my store, what's going on here.

So I get this and I can see there's the standard resiliency, the poly that's coming in for me automatically. So I get that all right there for me. Now I do want to go back though to that health check. So if I come back over here, I want to show off that if I come in and I go to the slash health.

Here, I'm going to see that I get the healthy coming in, which is what I would expect, right? Now, if I go over into my backend though, and I come in to here and I say slash health, I'm going to get the healthy again. What I'm going to do is I'm going to come over.

I'm going to stop that Redis cache. I'm going to say stop. And now what I'm going to do is I'm going to refresh this.

And now this is going to circle around. It is going to check all the dependencies because the standard health check system is now looking to see is everything that the API is using. Is it healthy? And it's unhealthy.

If I come back over here, we're going to see sort of the same thing now in this case. Yeah, the backend is still running, so it's still healthy, right? But the backend itself is unhealthy by changes to slash alive. We're going to see that.

Yeah, the API is healthy, but the dependencies are not. So I get those built in automatically. which is nice.

You can configure that as well. Now this is going to come back as unhealthy. But as soon as I start back up that container here, we're going to see that now it's unhealthy.

Now this is all coming in and it's listening to us. If I zoom back out here, and I stopped this container, we're going to see that that has been exited there. So the dashboard will also show us in real time what is happening, which is super duper nice to see. I should also see if I zoom out a little bit and I've been hiding it here. is that there were errors that occurred.

So it actually shows me that as well. I can click on that and go directly into the errors that are happening here. Of course, if I start this backup, I go back to my resources. Now it's going to say it's running and I've already taken a look at those errors, which is super cool.

So from start to finish, what have I done? Over here, I also like this. It also closes down all the containers for me automatically.

So in just a few minutes, I've added the app post, the service defaults, Visual Studio is configured all for me. I got all. of my standard open telemetry, health checks, service discovery, standard resiliency, configured all the exporters for open telemetry, added health checks, configured them for me automatically in my backend, in my front end.

And then I set up orchestration, service discovery, and I added Redis and Redis commander in just a few minutes. And inside of this, with the integrations, those NuGet packages for Aspire, it has configured all of the add-ons. additional health checks, the logging, and all of the standard resiliency and service discovery for the Redis here.

And I could go in and I'll add any different databases or different configurations and different integrations I want into my projects. Okay, so what did we just see? Well, we took a look at those first five building blocks, which are part of.NET Aspire.

The defaults, the dashboard, orchestration, service discovery, and integrations, and how they all work together to make our lives as developers better. We just can opt into this automatically and a lot of things that were difficult or frustrating before get better. And so do our applications.

Let's do a little refresher. First, smart defaults, observable, resilient, and health checks. We opted into telemetry into our application, which we obviously saw in the dashboard, which is really excellent to see. Our integrations added into that observability.

We could see our errors. We could see our issues. We could see bottlenecks and we could diagnose them faster on our local machine. Our applications were more resilient by opting into those resiliency packages.

So when we had issues, the automatic retries kicked in and of course they're completely customizable. Then because health checks were on not only for the complexity, the whole part of the application, but individual services, we could see in real time how our applications are doing, and if one of the dependencies are down or something is going on. We can extend all of those because there are standard ASP.NET Core and.NET APIs.

We also saw the developer dashboard really giving us insight into those metrics, into those distributed traces, into those structured logs from a single place. I really like that. No more thousands of Windows popping up when we're building and starting up our application.

They're all right there for us. Now we also took a look at orchestration, part of the app host. This enabled us to basically give us a C sharp definition of what to start up in our project. So we had our API service and we had our front end and our application just booted up.

No longer do I need to configure big JSON files. I don't need to go into VS and actually do a bunch of multi-project setup. It just knows what to start up my application in debug mode, which is awesome. It builds them, compiles them, starts them up automatically.

Even better of course, is the service discovery part, right? Enabling me easily to connect those components together. Here where I'm defining with reference the API service, my front-end can discover that API service from that single key, and I can define schema for HTTPS or HTTP or both together.

Now, the great part here is that there's still connection strings. What's happening, like I talked about, is that.NET Aspire at build and deployment is creating those connection strings based off of those names that we're giving it. Which means if I was just to deploy this exact same application today, I could just still opt into service discovery, but set these specific connection strings inside of my web application that's deployed anywhere, which is really great.

Now the integrations are really unique and there are tons of them out there. And I only looked at of course, Redis today, but I browse through some of the catalogs and there's tons of different vendors out there building aspire components as well. And they're all available as a NuGet packages, which is great. And like I said, they opt into different services, right? You get.

all sorts of goodness. Now let's talk about deployments. I know it's probably the question that's on everybody's mind right now.

How do I deploy this thing? Well, let's first talk about deployment. In my personal opinion, it is complicated. Like everyone in general wants to deploy applications in a different way.

You might have different it departments, different requirements, different CI CD. You might have different dependencies. You might have different security requirements. There's a bunch of different choices and every single application. is different.

If I was to survey every single one of you that is watching this video right now, watching this presentation, I said, how are you building your app? And you put in the comments below, right? Just let me know down there.

Let me know what components are in your application. I bet that we would get hundreds or maybe thousands of different answers because every application is unique, right? Which means it's complicated.

There's no one solution for deployment at the end of the day because of this, right? All we can hope for is that there are nice sort of ways of exposing an API that we can integrate into these different requirements for our company and our applications schema that we can opt into. Now, the nice part about.NET Aspire is that you can continue with one of many different deployment options. I mentioned it earlier, which is that you can just continue to deploy today.

You might have existing databases. You might want to deploy them to VMs, to App Service, to AWS, to Google, to Azure, wherever you want to put it. Maybe Kubernetes services, maybe container apps, maybe somewhere else, right? Who knows what you want to do?

If you are already deploying your application, you today can just update some connection strings. You can then deploy your application. You can right-click publish to App Service.

Whatever you want to do, you can continue to do it. In this example, we saw that I was using a connection string already. I could just update that connection string, and I could adjust to that schema that.NET Aspire is using. The important part here is that there is nothing in.NET Aspire to deploy.

The app host doesn't get deployed at all. The service defaults don't get deployed. You're still deploying your individual components, which means that is what enables you to deploy today. Now, on top of that, though, there is a way to streamline deployment, especially in development to help you get applications up and down really quick or even into production.

There's ways to do this using different services that can opt into things, such as the Azure Developer CLI and even Visual Studio. It's all optional, whatever you want to pick and choose. I'm going to talk about how this works.

Well, there's basically tooling that integrates into the.NET Aspire manifest that can be generated. AZD does this, the Azure Developer CLI. Visual Studio uses the Azure Developer CLI to deploy to Azure Container Apps. What it can do is it can ask the app host file, please generate a manifest. We're going to take a look at that of what is in your app.

Then the Azure Developer CLI, for example, can say, I'm going to go turn this into Azure infrastructure. There's a great community project out there called Aspirate, which I'll put a link in the show notes as well, that can take that same exact manifest and turn it into a definition to deploy to Kubernetes. Now the great part here is these are all optional.

So if you want to just continue to deploy your application just like you have been forever, keep doing that. That's awesome. Keep deploying your application.

If you're using.NET Aspire and all of the amazing things into your application for telemetry and everything like that, you will have access to all that on your local machine to make local app development better. If you want to deploy lots of options out there, including exactly how you're deploying today, and I'll reiterate that about 1,000 times. So let's go ahead and deploy some things. Let's get into it.

Okay, so how would I go ahead and deploy this application? Well, there are a few ways like I talked about. One is, yeah, I could just simply go and right-click and sort of publish my backend, right-click, publish my frontend wherever I want.

I could figure the environment variables just like I would expect, and then I would figure out how to deploy either Azure Redis cache, or for example, deploy the container somewhere as well. So that is an option, right? Now, my application, again, every application is different. So you can continue to deploy your application exactly how you have been, but just configure your different environment variables.

So everything sort of works when you're deploying your apps. Now it's important to remember when you're deploying any projects, you're not deploying an app post. The app post isn't something you deploy.

It is a definition of a distributed application. The service defaults, those are just defaults. That is just literally, is literally just a class library, nothing else in there with a bunch of NuGet packages, with some nice things that you can extend.

Inside of here, your app host is just a definition of what your project is. Now with that definition, some cool things can happen. Yeah, you can actually come in and say, hey, I want to deploy all of the things inside of the app host. Well, Visual Studio, for example, can deploy your.NET Aspire app host project and the things inside of it, through Azure Container Apps and the Azure Developer CLI.

Again, it's not actually deploying your app host, but it's going to deploy the projects inside of the app host and any of the dependencies. Now I'm going to show you exactly what and how this works under the hood and how other tooling such as aspirate, for example, extends this, uh, because this uses a done at aspire schema to know what to actually deploy. So let's talk about how this works. Okay. So the first thing that we want to do is it.

not deployed from here, though I am a big fan of deploying from it. We actually want to go in and I'm going to go ahead and copy this path. I'm going to open a terminal over here and I'm going to say CD over here and just go into my app host CD.

There we go. And I'm going to go into the folder of the app host. And there we go. So I'm inside of my app host. So there's a few things that I can do.

So first, I want to show you that you can do dotnet run. And I'm going to use this command, which is dash dash publisher manifest output path, aspire manifest. This is basically going to say, hey, for my outpost, run it, but actually don't run it normally, run it and generate a manifest and put it inside the folder that it's running in and called it aspire manifest.json.

Now this aspire manifest, as I open this up, is a definition of everything that's inside of. This, when it runs the application, it's a declaration for any integration tooling, such as the Azure Developer CLI, to know what to do with the configuration that we've set up inside of here. So if we look over here, we can see that this is the schema, and it has a bunch of resources. And those resources are going to tell any tooling that is out in the world today what and how to actually deploy this thing.

So the first thing is that there's a key called cache. It's a container. It has a connection string over here with the TCP ports and the host URL has an image, which specifically is from Docker IO and has these bindings over here.

It has some products and this is going to go off, uh, and say that this product is a project. Here's the path. Here's all the environment variables that you need to set up, including this connection string of the cash, because the products uses the cash. It's also going to say, Hey, Here are the bindings, so HTTP and HTTPS. And then additionally, the store is set up.

And again, it's a project. Here it is. Here are the environment variables.

But just like we saw in the.NET Aspire portal, here are those connection strings, right? And then here, for example, are the bindings. Now, one thing that is really unique that I want to point out is that by default, the schema is leaving everything private. So it's not exposing anything in any... ingress or egress it is just saying hey make these private so we're going to actually update this over here and i'm going to change this because i want the api to be private internal but i want the store to be external so i'm going to tell the manifest i'm going to say with external http endpoints okay and now i'm going to go ahead and rerun that command just like that it's going to create a new manifest for me perfect i'm going to open it up Now, we can see that under the store, we see external is set to true.

That's here. On this own, this doesn't actually do anything at all, to be honest with you. This is just a schema that anything can use.

Today, as of time of this recording and I hope more tooling come up, the Azure Developer CLI can take this manifest and turn it into Azure infrastructure to deploy it as of today into Azure Container Apps. But there's also aspirate, which is an open source community project that can take this and turn into Kubernetes deployments, for example, which is really cool. Let's see how AZD or the Azure Developer CLI can take this schema and turn it into specific things for Azure. I'm going to come back over here.

The first thing I'm going to do is I'm going to clear this out. I'm going to say AZD. Now, if you've never installed AZD, you can install it with WinGet or install it manually. here, but the Azure Developer CLI. If I just say AZD, we can see up here that this is the Azure Developer CLI that helps you manage your Azure applications.

Now, there's a bunch of stuff in here, but most people show up as doing up and down. You can deploy, you can provision, and you can do this here. Now, the other thing is just AZ, not AZD.

Now, AZ is the Azure CLI, and this is basically looking at all the different endpoints and things that you can. use right so this is the azure command line that's there but we want to use the azd command here so i'm going to say azd init that's the first thing here and we're inside of the app post so yeah use the code in the current directly directory it's going to scan the app code and it's going to say yeah let's initialize it it says azd will generate the files necessary to host your app in azure container apps and again that's what's available today as time of this recording but as you can imagine, if more services are supported by AZD, you might have an option here. Is it AKS?

Is it ACA? Is it app services? Is it something else? Who knows?

You know what I mean? The possibilities are endless based on your application. So I'm going to give it an environment name.

I'm going to say tiny app, tiny shop, YouTube here. Okay. Hit okay.

And it's generated a few files called azure.yaml and next steps. So if I go back over here, you can see here's my azure yaml. just has a little bit of information about what to deploy. The host is container app, and it's going to tell me the next steps of what to do. Now, at this point, normally what you're going to do, and I'm just going to clear this out, is do azdup.

We're not going to do that. We're actually going to say infrasynth. Now, it's an alpha stage, again, of a time of recording this, and I've turned this on, but the infrasynth is going to output files that azdup would... normally generate for us. So when I do AZD up, it does an infrasynth, but basically it does all the creation of the Bicep infrastructure in memory.

But I want to take a look at it and show you behind the hood. So if we go up, we're now going to see in the app host an infra folder. Here we're going to see our Bicep file. So this is going to give me information about my subscription. It's going to give me information about all of the outputs that are going on.

I have the parameters that are getting piped in for principal environment variables. I can also see my resources that are getting piped in for managed identity, container registry, authorization, role definitions, service principles, all sorts of things going on here. Then I can also see that I have these templates for the cache YAML, and this is the definition of this specific Redis cache.

So we can see here the ports that it'll be run on that it's TCP, the server, the name is the cache. that we have the Azure client ID and then the different services. If I go into my products, same thing. We can see that we have the information that's required for it to be deployed.

So here we can see that it's HTTP, that it's going to allow and secure, the external is false. Again, that is coming from that aspire manifest file. It's going to understand that it needs the connection string cache, the port IDs, and all the different telemetry coming in here. Same thing for store.

The difference is that we're going to see that the external is set to true, which is super cool. So that is all set up there. All right. So it has created all that for me automatically. And if I build and compile an AZD up again, it'll regenerate all this for me or resynth that is generated every single time based on my app.

So now at this point, again, I can just do AZD up. And now what it's going to do is I've already logged in. So it's going to analyze the aspire application. It's going to initialize the bicep provider. It's going to look at all my subscriptions.

It's going to ask me which one to pick. It's going to retrieve the locations that are valid for me. I'm going to say there's all of them here. I'm going to say West US.

And then it's going to set up and start to... deploy my resources inside of Azure, inside the West US location. Now, it's going to set up the resource group, it's going to create the resources, it is going to deploy my containers into Azure Container Registry, it's going to set up log analytics, it's going to set up my identity, everything that I need automatically for me.

So this takes a few minutes, usually around three minutes or so. So I've actually deployed this ahead of time. I'm going to open this up and take a look what it deploys.

Here we can see, yeah, it has my log analytics, my managed identity, has my container registry, it has my environment. If I tap on the container registry over here, we can see if I go into my repositories that I have the tiny shop, my products and my cache here. Here it is, my deployment from EZD deploy automatically.

If I come back over into my tiny shop, and I look at, let's say my products over here, we can take a look at this. Yeah, we have internal API here. We also have a dashboard, so I can open that up and I actually get an Aspire dashboard right here ready for me.

It's been deployed with it. You can turn it on and off. Previously, when you're running the Aspire dashboard locally, it has an API key that's passed around, but this actually logged me in with manage identity automatically. And this is going to show me all of my different containers that are running. I can click on the store, for example, and sure enough, I can look at the products.

Now we'll see again, the backend should be up and running in a container. And ideally here it should be running. Let's see if the backup is here running.

We're loading and there we go. I can now again, look at my traces and sure enough, most likely, I bet there were some exceptions. Yep. There we go.

I can look at those traces and see here we have our Redis cache that's configured and running and putting it in automatically. So by now, if I refresh, it's a lot faster. Go back to my traces and I have this up and running real time, which is super cool. Now, this is an Aspire dashboard. It's more for real time, right?

If I actually wanted long, long term and I wanted real deep insight into my application, historic data, I'd probably configure Azure Monitor, Application Insights, all that goodness. You can turn up. on and off all these things right here with a single checkbox and you can switch from log analytics to azure monitor other things right here i can figure that in your app as well but if i'm just a developer and doing ezd up and ezd down and doing things like that it's nice to see that in real time or flip it on there so there we go we have all that there configured for us let's go back and see yeah sure enough look at that we have our container environment and our resources everything like that now from here Again, you can, of course, right-click and you can publish and you can do all the things and you can add a publishing profile that you'd expect and you'd get that information in Visual Studio. So it's up to you if you want to use the command line, you want to add that publishing profile right here, totally up to you.

This is using this same exact mechanism under the hood. But it really is just that easy with a few lines of code to get your application up and running and deployed in Azure Container Apps with AZD or Visual Studio. Of course, you can continue to deploy your applications exactly how you are today, however you like in doing them. Of course, definitely check out ASPRIT, I'll put a link in the show notes, so you can check out other types of tooling that has been built specifically around this awesome Aspire manifest file that is generated. Okay, so we have deployed our application, we've taken a look at the manifest, how AZD uses it, and so much more.

Now, this application was using all things.NET, but.NET Aspire actually goes beyond.NET. That's right, because different applications have different needs. So you might, for example, have a Node.js front end, for example, maybe a React or Vue or Angular front end. You can integrate that into your app host and start up those applications and pass variables between them as well, which is really unique. It not only works with NPM apps and Node apps, but also Python applications as well.

You can add any Python project. Here, for example, we can see how I'm adding an Angular app. I'm adding references to the service discovery. I'm adding HTTP endpoints.

And I can even publish that as a Docker file out there as well to easily integrate. You can use the same extensions in these different integrations. So here in the dashboard, now this is from the docs. You can see that we're running an Angular React and Vue app alongside calling into our.NET API.

So you can integrate those in. And if you have your favorite Python project, you can easily boot that up as well, which is really cool. Now let's talk about that developer dashboard because everyone loves it. And they're like, wow, what if I would just like to use that? I'm already integrating open telemetry into my application.

I would love a great, awesome local developer dashboard on my machine. Can I do that? Can I use that?

And the answer is yes. The dashboard of course integrates into the app post. Like I showed you to easily start up the projects, boot up the dashboard, do everything, but you can also use it standalone. And in standalone mode, it's just a container that you can pull down and run locally.

With a Docker run command, you can easily download it, boot it up easily enough, and then get access to the same exact developer dashboard that we saw earlier and pipe telemetry into it. That's really, really nice because with that container, you can of course then deploy it and configure it anywhere. So let's take a look at how we use that standalone dashboard in any different type of application.

All right, a great place to start is actually aspire dashboard.com. It's a nice little website that perhaps myself and a few other people put together. That's open source static web app out there into the world.

But I like it because it's a great domain name that just gets you right to the aspire dashboard shows you what it has screenshots, how to get the container image, how to log into it, how to integrate into your applications, which is really just installing open telemetry and the gRPC export is all you really need to do. This kind of walks you through it. Now there is also samples here, so you can just tap on samples and download them.

And there's one for each programming language. So let me start first with the console app and C-sharp because again, you know, you can just have any application and C-sharp like a Maui app, like a council app, like a background worker service, something like that. And you can just integrate open telemetry in it. So here's open telemetry up here.

And then what we have is this little open telemetry configuration, which looks very similar to what we saw in an aspire, almost one-to-one. But it adds a little bit of configuration, like the service name, for example. And it also, of course, configures the exporter, which is coming from the launch settings here.

So here's that URL that you need to have there, which is great. So inside the readme is going to be that command that you need to run. So I'm going to go over to my terminal and just paste it in there. And that's going to download it.

And I don't have it. So it's going to install and get that image over here. So there's another one. And boom, there it is. And now it's in use.

Amazing. So we have it here and then we actually need to click into it and get the logs. So if we take a look here, we can say there's a URL here with this code.

So I'm just going to go ahead and copy this code first. I'm going to click on it. Boom.

And we're going to see that it's a big white screen and we're going to replace zero zero zero with local host over there. So we get our Aspire dashboard. Let's go and put it in dark mode for us. Perfect.

Now this is running in an unsecured mode, so we can always, you know, do more authentication and HTTPS and things like that. But we have our, yeah, our spire dashboard just up and running here, which is cool. And then we get structured logs, we get traces, we get metrics, we obviously don't get like what projects are running, because it's not running projects, right?

So we get a slimmed down dashboard here. But let's go ahead and run the application. There we go.

I'm just going to go ahead and run it. And of course, this is now configured. For bit telemetry is going to download all the latest packages and we can see the output here. We can see a bunch of information coming inside of here, which is really great.

And we're going to go ahead and go and then let's look at our dashboard. Let's see what happened. Yeah, sure enough, right here we have all of our structured logs for our console app. You get information about the different packages being downloaded.

I can look at the trace that's going on here that is calling the API and then Azure search to get those down. We look at all the traces. So again, there's just that one big trace and we can look at metric.

So here's the console app and we get different information that's configured for assembly count and Allocation sizes and GC things and things like that. And here's all of our active HTTP requests Connections that were happening and you can put that in a table or anything that you want So you can get all these different types of information, which is really really cool all in real time So super simple to pull down get up and running just right on your machine. So really simple to do So the other thing we can do, though, is I'm going to open up VS Code and I have a JavaScript application.

So it's just a Node.js application. And this comes from the OpenTelemetry samples, but I've customized it. So it's a little dice roller and it's just using Express.

And we can see that there's one API roll dice and you give it a number of rolls. And then it will do a bunch of math on it and roll the dice, basically, and give you back information. Now, what I've done inside of here is that we have.

you know, configured here, the different tracers and metrics inside of here. So if I look at instrumentation again, this is kind of just coming from the open telemetry documentation, but this sets up open telemetry, everything like this. So if you already have open telemetry in your application, you're good to go.

All you need to do is set up the GRPC exporter, which is on here as well. So it's kind of nice to see. So I'm just going to run this just like that.

All right. And this is going to open up a local host. Boop. There we go.

Well, it's very bright. And then I'll say rolls and the aerosol. I guess I'll say get was the API.

Let's take a look here because I should know what it is. It is roll dice and then rolls is what it's looking for in the query. So roll dice rolls equals 100. There we go. Now we get the roles back, right?

We can do, let's say, ten here. Boom. There we go. We can go back over to our structured logs and we can see if we go down here, we can see the dice server and sure enough, there's our two calls that were coming in from the logs. I can take a look at the trace.

There we go. And we can see exactly what's happening. We see the middleware query, the express in it, the roll dice, call it all the rolls and how long they took and go back into the traces. And sure enough, I can filter on all or I can filter on dice roll.

You can just see just the ones that were coming in. So I can see all the different bits of information that's coming in here. So that's really nice.

And of course, you know, you can come in if I had different information besides trace or debug, I could filter, I could do all sorts of, you know, advanced things inside of here as well. So it's a really nice way of using this in any application that's out there. And again, you can just go to, you know, aspire dashboard.com and definitely give it a go and then check out the official documentation.

It's open source on GitHub, community, the discord channels and a bunch. more. All right,.NET Aspire. So many amazing things for building better applications from the smart defaults to that graded developer dashboard to orchestration service discovery, plethora of different integrations, and of course, a bunch of different deployment options, including exactly how you deploy today with a few tweaks to those great connection strings..NET Aspire lets you build better applications locally, build better applications for your users, and easily deploy them to get them up and running and scale and manage them faster than ever. and it's flexible you can pick and choose which of these different building blocks that you want to integrate into your apps and customize them exactly to your app needs all right let me know anything that you have down in the comments below there are tons of great resources that the dotnet team has put out from full getting started videos amazing documentation there's an entire learning portal and great microsoft learn that you can go through self-guided learning for this and of course everything is open source on github All right, there you have it.

I've really been thinking a lot since launch of.NET Aspire about how I talk about.NET Aspire, what I demo with.NET Aspire, and basing that off the questions that I've been getting, incorporating that into my demos and my presentations. I hope that you enjoyed this presentation style. If you did, make sure you give it a thumbs up, jam that subscribe button, of course, ring that notification bell so you get notified every time I put out a video here.

What do you think about.NET Aspire? Are you using it inside of your applications? Are you using AZD and deploying it to Azure?

Are you using Aspirate? What are you doing? and what are you building i'd love to know more and build some great content around that let me know in the comments below everything that you think about.net aspire.net in general and of course dot at maui c sharp and all that other stuff so i'd love to learn more about all my amazing viewers and what you're building and how i can generate even more great content right here on the channel what's gonna do for this video i really appreciate all of you for taking the time to learn dotnet aspire with me so until next time i'm james thanks for watching