 Welcome back everyone to Visual Studio for Mac refresh. I'm Jeff Holland. I'm a program manager in Azure Compute focusing on serverless, and I'm really thrilled to have the chance to talk to you all today about bringing serverless to macOS, we're going to be using Visual Studio for Mac the entire way. So I want to share with you insights about what serverless is. It's a buzzword that like many buzzwords is probably overused a little bit meaningless now, but there is some good stuff there. So we'll talk about what serverless is, the kinds of apps that you can build, and then really we're going to dive straight into using Visual Studio for Mac to write serverless apps, walking you through the different tools and techniques and patterns that you can use to develop, debug, test, deploy, and monitor those apps in production. So to start with, the first thing I want to talk some about is what is serverless? As I mentioned from the beginning, it may be as a term that you have heard before, and if you have, it's one of those wonderful words in technology that's a little bit overused. So let's just start with a very simple definition about what serverless is. So serverless has a few different characteristics that define serverless compute. So first and foremost, serverless is really about letting you say, hey, I want to write an application, but not have to worry about a lot of pieces of that application that traditionally I would need to worry about. Think about if you were building an app that needed to be called from the web maybe 10 years ago, right? You could go, you could buy a server, you could install an operating system on that server, you could plug it into a power source, connect it to the internet, make sure you have enough hard drive, make sure you have enough CPU, make sure that your keeping security patches up to date, expose it to the internet. There's all of these things that you need to do before you even start writing your first bit of code. And what serverless is about is saying, hey, just write your code, focus on your code, deploy it, and all of those other pieces that I mentioned, the managing the operating system, keeping it secured, securely exposing it over the internet, those are all taken care of for you by Azure. Now, the other aspect of this is with serverless, you only have your code running when it needs to run, meaning if you deploy a function that says, hey, process this time card, whenever somebody submits their time card at the end of the week, here's the bit of code I want you to do to enter that into our CRM or whatever else it might be. During the week, if no one's submitting their time cards, that code isn't even running. You're not paying for it until finally a time card gets submitted. Azure recognizes there's an event and it spins up and executes your code on demand. Maybe a million people submit their time codes and so you'll get a million of these executions that happen automatically. So that means serverless is event driven. There needs to be some event attached to your code to let Azure know when it should run and execute your code. And those events are very flexible. It could be whenever I create a resource, whenever it's Friday at five o'clock, I need you to go do this thing to a virtual machine. I mentioned things like business events and when submitted a time card, a new customer signed up, you get the idea. Then finally, as I kind of mentioned with that event driven, one of the pieces of serverless that make it very appealing is that you only pay for those resources when you're actually using them. And you get dynamic elastic scale out of the box so that you have the compute that you need exactly when you need it. So at the core of serverless compute in Azure is Azure Functions. I have a little snippet of one here on the right hand side of the slide, but you'll see one in action in a second once we jump to Visual Studio for Mac. But Azure Functions allows you to deploy your code. The rest is managed for you. You could use C-Sharp, PowerShell, JavaScript, Java, Python. You can use a number of different tools, including Visual Studio for Mac. And it allows you to trigger on over a dozen event sources. Some of the ones I've already mentioned. So we're going to be using Azure Functions and I'll show you how you can very quickly get started writing just a little bit of code, publishing it and managing in the cloud all from my Mac. Now what are a few ways that we see folks using serverless compute in Azure Functions specifically? And I wanted to call out three big patterns to kind of set in your mind before we even start walking through some of the nitty-gritty details of building them. So the first one that's very possible and especially appealing for Visual Studio for Mac is this mobile application pattern where you have a mobile backend. So imagine you have a mobile app. Maybe this is a Xamarin app running across windows, iOS, Android, you name it. Somewhere in the process of that app, it's very possible it needs to call out and get some data from the cloud. Now you could spin up a full website or a web API to do this. You could spin up a Hervotra machine. There's nothing wrong or right with any of those answers, but a very common pattern to say, hey, I need to call, my mobile app needs to get information, list recent blog posts, list recent promotions. Maybe I could just call a simple Azure function behind the scenes, have that function go retrieve the details, and then return it back to my mobile application. In fact, one of our largest customers, it's a major retailer. They have a mobile app that allows you to build and purchase credits that you can gift. So you could say, hey, I want to give Jeff a $10 gift card to this place to power that experience, the purchasing of the gift card, the emailing it and the notifying of the mobile devices. They've chosen to use an architecture much like this, where they're calling API management, which manages those different API layers at a single spot, which is just proxying the request back to a serverless Azure function. And that Azure function is making some communication with some state. This could be SQL, could be Cosmos DB, could be storage, and then they're turning that back to the mobile application. So this is one very common pattern and a nice place to use functions is as that compute backend to mobile applications. Now the second pattern is about processing events. I think about this like event streams. So for example, imagine that you have a stream of events coming in. Maybe this is stock information, like whether it's inventory stock or actual stocks like the stock exchange, or this could be diagnostic logs and you want to be able to evaluate and analyze those logs in real time, is they're coming in. Maybe this is IoT data and you have IoT devices that are sending events up to the cloud. This is a very common pattern. I often call this the bread and butter of serverless because it fits so nicely because as your events scale, as you add more devices, as you get more diagnostic data, your functions behind the scene scale automatically along with it. So it's a pattern that might look something like this. Maybe you have devices like an IoT device. They're sending messages up to Azure IoT Hub, Azure Event Hubs. Then you have functions that are processing that data in real time. Back to another major retailer, recently used functions during Black Friday where they have an event hub in the cloud that was getting events whenever somebody made a purchase on their website. They were expecting massive scale during Black Friday because they were having a bunch of promotions. But what made functions nice here is that it instantly scaled, processed those events and stored the details back in a Cosmos DB database. So another very useful pattern if you're thinking about, hey, I've got streams. I need to process these in real time. So maybe transform them or map them and stick them into SQL. Functions might be a great fit. And the last pattern I want to show, this one's a bit more cutting edge. Depending on the sessions for Visual Studio for Mac refresh that you've watched, this might be a pattern that even makes a little bit more sense than it could have before. This is about serverless web apps. So I'm not going to go too deep into this for the purposes of this session because I want to get to the tools very quickly. But this is around saying, hey, instead of deploying and running a web application like I'm used to, where maybe I would get an ASP.NET app or a JavaScript Express app and I would publish this and have it running in a web server. What if you don't actually have that server running? What if you could host a web application but have it be entirely serverless and you only pay when somebody goes and visits that website? So this pairs very greatly with things like Blazor. If you've learned anything about Blazor and the.net stack, really any single page application framework. What it means is that you take your website content like that HTML page that has some Blazor web assembly and instead of publishing it to a web server, you actually deploy it to an Azure storage account. So you say like, hey, my Blazor app and the index.html are all going to go to a storage account that I'm going to expose. Now, when somebody goes to something like JeffHallin.com or whatever your website is, they just pull down that HTML. Their client browser, whether it's Edge or Chrome or Firefox, their browser then renders that page. And when it needs to pull data from the cloud, maybe it's a news website and it needs to pull the top stories. It could call out to Azure functions that you've deployed in the web that can then populate that with real data. So by following an architecture like this using a service like Blazor and we even give sessions during the Blazor conference about doing this with functions, you can now take a website and host it entirely serverlessly so that it scales with massive events or also so that you're only paying when people visit it. So some pretty exciting things you can start to do with serverless. Some patterns that you can consider as we go through the tooling next and that's really where I want to go next. So let's now talk about how do I write serverless apps on macOS. So I'm going to go through a few things. We're going to create an app. We're going to test it. We're going to deploy it. And then we're going to monitor it and we'll go through a few different discussion points along the way. So I'm going to switch here now. I'll keep my slideshow on the background until I get this project. So I'm here now in Visual Studio 2019 for Mac. Let's go ahead here and create a brand new project. Now I love this section called cloud because when I click it, there is only one option that I have and it is the best option, Azure Functions. So right here, I have a template out of the box and all of your installs of Visual Studio for Mac that will assist me in writing Azure Functions. Now what makes this convenient is when I select this template, it's going to help me get started but it's also going to take care of things like local debugging and make sure that I have all the function tooling on my Mac. So I don't have to worry about going and installing anything else except for Visual Studio for Mac. So you'll see here, I have some questions. It wants to know the name of the function. So let's just call this one, Hello Visual Studio for Mac. And I have a bunch of templates here that I can get started with. Hey, is this going to be something that people can invoke over HTTP, a timer trigger, queue trigger, blob trigger event hub triggered, this thing called durable functions that we might get into a little bit later. Let's just keep this simple and we're going to start with an HTTP function, something I can invoke over the web. Maybe that's that mobile backend or that blazer backend. So let's go ahead and click next here and it's just going to ask me a few questions. I can set a key, which means do I have to pass in a key to execute this function? Do I want to make this anonymous so that anybody who has the URL could execute it? So I'm just going to stick with function. It's going to generate a key for me that you'll see in a second and ask me a few other questions. Do you know the project? Do I want to use get? It tells me a little bit about what my project structure is going to look like. So I'll go ahead and generate that template now. And Visual Studio for Mac has gone ahead and scaffolded for me now an Azure Functions project right here in Visual Studio. So a few things to call out. This is it. This is all the code that you really need to get started with. There's no other files that are have code except this Hello Visual Studio for Mac file. It's a simple class and I have here a function name. So this one's called my Hello Visual Studio for Mac function. I could call this any other function. So I'll just rename this to Hello. And here using C-sharp attributes, it's automatically defined for me. It said, hey, Jeff wanted this to be an HTTP trigger, function key, allow get and post. I could create a custom route here. So I could say like my custom and have some like path parameter here if I wanted to. It's going to pass in an HTTP request. It's going to pass in my logger. Now I could and I won't for the purposes of this talk, but I could go and add things like dependency injection or I could start installing other libraries. I could really run anything I wanted to in this function app. But for the purpose of just getting started, let's just stick with what we have here. So we'll walk through the code simply. It's not doing a whole lot. It's going to log a statement. It's going to pull out a name query parameter if one is provided. It's also going to read the request body if this was a post. So it's going to try to read the HTTP request body. It's going to pull out the HTTP request query. Based on one of those things, it's going to try to get my name. Either my name passed in through the body or my name passed in through the query parameter. And it's just going to turn back a very friendly hello. And then my name rest me to pass in the name. So again, what's nice here about using Visual Studio for Mac to write this process is that I started this new project. I haven't even made any changes. I guess I changed the route a little bit in the function name. But I can go straight into debugging. So let's go ahead now and run this project. Visual Studio for Mac is now going to compile the code. So it's going to do a .NET build. And you'll notice here it's spun up a terminal window. Now the blue might be a little bit hard to read. So I'll try to zoom in here. But you'll notice from this beautiful ASCII art, what it's spun up in this terminal is the Azure Functions runtime. So Azure Functions is completely open source. So the runtime can run anywhere. It's cross platform. Written actually on .NET Core. And in this case, that open source Azure Functions runtime is running on my Mac in a terminal through Visual Studio for Mac. So the Azure Functions runtime is spun up. It's discovering my code. It's spitting out a few log messages here to tell me about the things it's discovered. You can see right here, it's actually said, hey, I see your code. You have an HTTP function. And this is the path that you can either get or post. So now because it's running locally, it's on local host. And you can see here's my custom route that I set up. So let's go ahead and test this out quickly here. So I'm going to open up iTerm. Woo, zoomed in a little bit there. Let's go ahead and we're just going to curl this endpoint. And we will pass in. Let's get rid of this path thing that I set up. So we will say my custom foo. And let's do that query parameter of name. Name equals Jeff. So that's the URL. I passed in my name. I push enter. And you will notice it says hello, Jeff. And if I come back over here, we'll even see that the logs all processed here. I can debug them. It says, hey, there's my log message that got kicked off. I got the response I expected. I zoom out a little bit. Trying to zoom in so everyone can see. It's even better. I get to do all the things that I would love to do when I'm debugging a project. So if I go ahead and just set a breakpoint and execute this function again, look at this live debugging. Hooray. I love it. So I can step through the code. I can look at, oh yeah, that was the name. The name was Jeff. That's very small. But I realize you're like, oh yay, congratulations, you set a breakpoint in some code. I've been able to do that since 1975 or whatever. But it is, serverless is a new paradigm of compute. And there's a lot of options out there that doing something as simple as what I just showed you, creating a new function, triggering it locally, setting breakpoints, isn't always super easy. But Visual Studio for Mac and Azure Functions make it that way. All right, so now that we have the basic setup for an HTTP function, let's spend some time and talk about some of the other ways that this project can then be extended. So we've gone ahead, a few files that I skipped over before that got generated that I'll call out now. So one is this host.json file. This is a part of every Azure Functions project. You'll see right now my host.json file is pretty empty. It's not doing a whole lot. All it says is the version of the host.json file. This is a file that I can use to set up configuration options for the function when it's running. So for example, I have an HTTP function here. This HTTP function could process a number of requests concurrently on every container, on every server behind the scenes that it's running. I have some options here to say like, hey, for HTTP, maybe I want to set things like the, we'll see here, the options, like the max concurrent requests that I want to allow per instance. So for instance, if I select that, I could say, you know what, for every instance that this is running around, I only want to allow up to 100 requests. And after you get 100, you need to start queuing them or even potentially returning back for 29s. But they guys need some flexibility. Maybe my functions doing some really heavy lifting. I can go ahead and use the host.json value, the host.json file to set some of those knobs. I could do it for other triggers too. But remember, this host.json file is valid for every instance of the function. Remember that, because in a second here, I'm going to show you functions at scale. And when you throw a lot of load at a function, we're going to spin up a lot of these instances. You can think of it like VMs or containers. We're going to have a lot of these containers behind the scenes. What the host.json file lets me do is say, this is the value for each one of those containers. So I may very well, if I had 10 function containers running, and I had the value of 20 concurrent requests per host, 10 times 20 is 200. So globally, I could be processing 200. So something you might get hung up on. The other file here that we'll go into quickly is the local.settings.json file. Now, local.settings.json file is where you can configure your environment variables, your application settings that will get automatically loaded into your local debug experience. When you publish to the cloud, you don't have local settings. You have what are called application settings. But for example, if I was using a storage trigger or an event hub trigger, and I needed a connection string, this is where I would add in that connection string. So I'd say like my event hubs connection string. And then I would put in that super secret connection string here. And this you'll notice with that X is not checked into source control. So I don't have to worry about these secrets getting checked into GitHub. But this is where I would put them. Okay. All right. So I'm actually going to switch over to a different solution. Now that you understand those files and show you a little bit more. So this is the hello solution. Let's go ahead and close this project. Same idea here. I've just written a little bit more. So the first off, I have my starter, which was an HTTP function. This is just like the one we were looking at. But I've added a second function here. This is an event hub function. So this is going to be triggering on like IoT events or telemetry events in Azure event hubs. This is very much like Kafka if you're familiar with that. So here I have the attribute that says this is an event hub trigger. Now one thing I want to call out. It needs to know what event hub do I talk to? What is the connection? So here I say, well, there's an event hub connection string. Now where is that connection string? It's in the local.settings.json file. This is the secret. I can't scroll over or else you're going to see my connection string. And everyone's going to start using my event hub. But just to show you. So that's how it knows which event hub to talk to. I have here just a simple function that's processing event hub data. I had another one here. This is also HTTP triggered. But Azure Functions has this concept of bindings. Now bindings, it's not what's triggering your function, but it allows you to easily integrate or put data or get data from an event source. So in this case, in this single line of code, what this Azure Function is doing is it's getting an HTTP request and then it's sending it to Azure event hubs. But I haven't had to worry about configuring the event hubs SDK. I haven't had to worry about any of that because I use this binding here. I said, hey, I have an event hub binding. I want you to send events to the event hub called events. This is the connection string. And everything that I put in this collection called event output, I want the function to go put in event hubs for me. So that makes it so truly easy. Now I just say, hey, event output, here's another event I want you to send to event hubs. And now this function is sending events to event hub. I could use Cosmos DB bindings to easily send data to Cosmos DB. I could use Service Bus bindings to drop in Q messages, Twilio bindings to send text messages all following the same pattern. So again, this is how to use bindings. The other thing I'll show here before we publish is writing tests. So Azure functions should be tested, just like every other code that you're writing in Visual Studio should be tested. So I created another project in the solution. In my case, I'm using X unit, but it doesn't have to be. And here I can start to write some unit tests. So there's actually a document that we publish called testing Azure functions that will walk you through how to set all of this up. But it's pretty easy here. I just have a single test called test one. And I'm going to test that HTTP trigger. So I'm going to test my HTTP trigger. I'm going to pass in the query parameter bill. I'm going to run that trigger, hello dot run. And then I'm going to assert that it reaches the value that I want. So I could test any of my functions. This is just an example of a simple unit test. What I like to do too, even though mine's not showing right now, is this test pane on Visual Studio for Mac over here that I can see all the tests that I've written. So this is the hello test that I wrote. You might even be able to see grayed out is a green checkbox because I tested this minutes ago to make sure my demo didn't fail in front of all of you live. But if I go ahead and run it again, and I also crossed my fingers, it did not fail. All my tests passed. So if you want all your tests to pass, only write one test and make it very easy. And then it always passes when you have to do this live. So I can write unit test here as well. All right, let's actually switch back to my other project because I want to show you how to publish now. We have this all working locally. We have this now tested locally. How do I get it to run in the cloud? How do I get it to do that serverless scale thing? So all I have to do is right click the project and here you will see publish. And I have two publish options. I can publish to a folder. Maybe if I'm going to do my own manual publishing pipeline, or I could publish straight to Azure, especially when I'm developing. This is the option I prefer because I can just really quickly deploy it and then test it out. So I'm going to go ahead and say choose publish to Azure. Now for me, because I love Azure, I am a part of about 30 subscriptions. So this page might take a little bit to chug along while it loads all of my function apps that I have across 30 Azure subscriptions. So I would wait for this screen to finish refreshing for me. Oh, it's done. It wasn't actually that long. I need to write more functions. So here I'm going to go said, I could select an existing function, right? If I already had one and I just wanted to deploy on top of it, or I can create a brand new function, let me walk you through some of the options here. So first I need to give it a name. You can see here this name is actually going to turn into one of its URLs. So this needs to be globally unique. So I'm going to call this Jeff, Hall and Live vs for Mac because hopefully no one has deployed a function with that name. I can choose my subscription. I have my own personal subscription down here and a resource group. I could create a new one if I wanted to, or I can select one that I already have. And it looks like mine is a little unhappy at me right now. So I'm just going to type in one that I know I have called vs for Mac. And now here, this is an interesting one to call out. This is to know what's the plan that you want to run on. And this is where I don't want anyone to get confused because I was talking all about serverless and now it's like, well, I don't know which plan that I want. The serverless plan is this consumption one. Consumption means only pay when it's being consumed, scale it down to zero when it's not being used, scale it to whatever when it is being used. So if you just want the quick Azure function thing, the way we've been talking about it, choose consumption. These other plans enable you to run Azure functions on some higher hardware that's always warm that never scales to zero. So specifically these EP ones that stands for Elastic Premium or the Functions Premium Plan, these are bigger. They're never cold. So you never have like extra latency from warming up or cold starts. So I can choose those if I want to, but really consumption is probably where you're going to want to hang out. And then I can go ahead and from there select next. And I think this resource group one, I've made it, I've heard its feelings. So I'm not going to fiddle with it too much, but from here I can just push next and then publish and it's going to go ahead and publish that for me. Now, once it's published, what can I do? So we're going to switch back over here to the Azure portal. Here's one that as the name would allude to, I've deployed ahead of time, I pre-deployed it because I love being prepared if the resource group selector is going to be a little bit sad at me. So now here is the Function app, very similar to the one we just wrote that's now running in my subscription. So here I could test it out, I could list the functions, I could get the URLs. You can see here's the three ones I was showing you earlier, the hello function that returns back hello world, the event hub function that triggers on event hub, and add event that adds an event to that event hub. Here I can get the URL that anyone could now grab this URL and there's a code at the end of it too because I said function key and I could now have it return back my name. One important thing that you'll probably want to do though is turn on monitoring. So by default we've just deployed this without any monitoring, I didn't configure any, but you probably want to turn some on. So if I go ahead and click that monitor tab, it's going to say hey do you want to turn on application insights? And the answer should always be yes, you always want to turn on application insights because application insights is going to give you a lot more insight as the name would suggest into your function. So let me show you a little bit about what that looks like. Here I have a function with application insights, application insights is going to give me info on like the requests that are failing and how many requests are failing, the response time, I get these cool systems like my application map, actually I switch over to another function app because this has a cooler one. This is an application map, this is a function that I have. You can see it's at one point scaled out to five instances over the last 30 days and the application maps even giving me insight into the different services and dependencies that it's calling. So this specific function calls Twilio. So you can see here on average that takes about 400 milliseconds to call Twilio. I'm also calling the Azure APIs and that takes about 800 milliseconds on average. I'm calling storage queues, which only takes about 13 milliseconds and I'm calling this local endpoint, which sometimes takes about a second. So application map helps me understand exactly what my app is doing, if there's any bottlenecks, if I'm like, oh man, I should really beef up the performance on this Twilio call, it gives me insights to do that. And one of my favorite features for monitoring is this live metric stream. Now live metric stream will give me a real time glance into how my app is performing in the cloud. So when I turn that on, like I've just done back here, I can now do a live metric stream. So let's check that out here. This is a live metric stream. You will notice right now it says your app is offline and that is because the function that this is listening to, I haven't called it in like 20 minutes. So it's scaled all the way down to zero. But if I go ahead here in a secret tab, I'm going to go ahead and trigger that function. If we come back here to this live view, as the name would suggest, in real time and live, I've now seen that this function has spun up, that it's executed. I got one request that came in and I can see the container behind the scenes is actually running my function. So in this case it's B2D890764. It's one of the fastest containers we have in our service. I can see that running in real time. In fact, just to show you how cool some of this monitoring is, while right now I have one server behind the scenes, the last thing I want to show you, I'm going to go ahead and run this low test and throw a thousand messages a second at this function. And as soon as I do that, you can see the count of servers that we have online. Before I even finish this sentence, it's now scaled up to five, to seven, to eight servers all in real time because this is serverless. I didn't do anything more than what I showed you. I just wrote that function. I deployed it and then I threw a bunch of traffic at this thing and because it's serverless, it's taking care of scaling out and doing everything that I need for it, all written from Visual Studio for Mac. I'll debug the Visual Studio for Mac. Okay, so that was walking through the entire process. We created the app, we tested the app, we deployed the app and we monitored the app using app insights. We even threw a bunch of scale at that app to watch it be all serverless and amazing. So if you're interested in learning more, if you want to now go and try to build your own Azure functions, here's a few links to help you get started. So the first one here, aka.ms slash functions, that's going to take you to our documentation, to our quick start, so that you can get started right away writing in whatever tool or language you want. I showed you everything here using Visual Studio for Mac. If you want to download Visual Studio for Mac, the second link will take you there. If you're interested in staying up to date with updates or insights, as we continue to build out Azure functions and serverless and our integration with Visual Studio for Mac, you can follow us on Twitter at azurefunctions or myself personally at Jeff Holland. So thank you all very much. Hopefully that was insightful and we'll pass it back over here to Christos. Insightful for sure. I love serverless, I love functions and it seems like our audience loves functions as well. So we have a few questions. The first one is coming from Twitch, so you won't see it here, but the question was, what is the difference between Azure Functions v1, v2, and v3? Yeah, sure. So there are three versions of Azure Functions. The biggest one to be aware of is in v1, behind the scenes we have code, which is called the Azure Functions host. And that's the code that's in charge of triggering your code and getting logs from your code. That host, the Azure Functions host, was written in .NET Framework. So version one was .NET Framework 4.7 now. Version two, we moved over to .NET Core. So for purposes of this demo, I could not have written a v1 app because I'm using my Mac in Visual Studio for Mac, can't run .NET Framework there. v2 is written in .NET Core 2, v3 is written in .NET Core 3. So the biggest reason that you would change between 2 and 3, obviously bigger numbers are always better, so try to get to 3. But if you want to write functions that target .NET Core 3, then you want Azure Functions v3, which is the default. When I created that project, it was v3. If for some reason I wanted to use v2 or stick to specifically targeting 2.0, then I can use that v2 runtime. Perfect. The other question that we have, and that relates very closely to the versions, is are the functions created on Visual Studio for Mac with .NET Core 3.1 functions v3? Very recently, yes, they are. So this is a pretty recent update. In fact, if I come back here to the new solution screen, and I choose that Azure Functions project that I like, one of the things they've added in a recent update is this templates up to date. You'll actually see I have templates available. When you refresh this and you get the latest one, this thing that it's downloading that's toggling up these percentages, the latest ones will be targeting Azure Functions 3.0 using .NET Core 3. So all the stuff I was showing there, if I showed you below that ask error, it would say 3.something. So it's very recent, but it's there now. And if you don't see it, make sure you go to that screen I just showed you, make sure you're using the latest version of those templates. There you have it folks, fully supported. So you get the latest version as well, directly inside Visual Studio for Mac. Now, I know people build different solutions using functions and can be quite inventive, but one of the challenges that we've come across many times is testing things. So do you have any recommendations for unit testing Azure Functions on my Mac? Yeah, right more than I wrote. I showed a little bit about that in my session. I only had a single one. I think the biggest recommendation that I would give you actually that's made unit testing a lot simpler for me is about a year and a half ago, we released a NuGet package you can install into your function app that enables you to set up a dependency injection pipeline. So just augment all your function executions with like interfaces of the things you want to do. And it just makes writing those unit tests even easier. It's fully supported, but I would recommend using that dependency injection library and using dependency injection to take advantage of that inversion of control and all the goodness that that brings. And we have one final question. Thanks, Jeff. Someone has a monolithic AWS Java server solution with static services and restful services. Is there a best practices guide for migrating these portions over to Azure regarding all functions, database, and what have you? Yeah, especially if you have a legacy app, I think the first thing that I would I would be interested to know about are what are some of the major pain points? If it's purely about, I just want to host this in the cloud, honestly, sometimes what works best is just taking like Azure app services and just publishing that Java app as is. You don't even have to turn it into a function and you just run it there. Now, if you are worried about things like, hey, I actually want to decouple this a little bit. I want to make it more serverless and event-driven. My only advice there was just do it incrementally. What I see be most successful is you'll take bits of functionality and one at a time you'll say like, hey, I have this route here. I want to turn that into a function rather than trying to break the whole thing apart at once. It's definitely possible, but think about what are the major pain points you're experiencing now and then figuring out the right solutions and technologies that will address those pain points directly. Great. Thank you, Jeff. That was fantastic. As you can see here with serverless and .NET Core, the sky is the limit on Visual Studio for Mac. So we're going to cut into a quick break and then we're going to go to how to build Unity games with Visual Studio for Mac and .NET Core. So stay tuned. Thank you.