Getting Started with Azure Functions v3 and .NET Core 3.1
Azure Functions v3 has been generally available since December 2019, running on .NET Core 3.1 LTS. With the current push for cloud adoption during the pandemic, serverless computing is seeing increased adoption. Let me walk you through setting up a production-ready Azure Function.
Why .NET Core 3.1?
.NET Core 3.1 is the current Long Term Support (LTS) release, supported until December 2022. It brings performance improvements and is the recommended version for production workloads.
Creating Your First Function
# Install or update Azure Functions Core Tools
npm install -g azure-functions-core-tools@3
# Create a new function app
func init MyFunctionApp --dotnet
# Navigate to the project
cd MyFunctionApp
# Create an HTTP-triggered function
func new --name HttpTriggerFunction --template "HTTP trigger"
The Function Code
Here is a simple HTTP-triggered function with dependency injection:
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
public static class HttpTriggerFunction
{
[FunctionName("HttpTriggerFunction")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
Adding Dependency Injection
Create a Startup.cs file for DI support:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyFunctionApp.Startup))]
namespace MyFunctionApp
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IMyService, MyService>();
}
}
}
Local Development
# Run locally
func start
# Test the function
curl http://localhost:7071/api/HttpTriggerFunction?name=World
Deploying to Azure
# Create a resource group
az group create --name rg-functions --location australiaeast
# Create a storage account
az storage account create \
--name stfuncapp2020 \
--location australiaeast \
--resource-group rg-functions \
--sku Standard_LRS
# Create the function app
az functionapp create \
--resource-group rg-functions \
--consumption-plan-location australiaeast \
--runtime dotnet \
--functions-version 3 \
--name my-func-app-2020 \
--storage-account stfuncapp2020
# Deploy
func azure functionapp publish my-func-app-2020
Best Practices
- Use Application Insights - Enable it for monitoring and diagnostics
- Implement retry policies - For resilient integrations
- Keep functions focused - One responsibility per function
- Use managed identities - Avoid storing credentials in code
Azure Functions v3 with .NET Core 3.1 provides a solid foundation for building serverless applications. The combination of the mature .NET ecosystem and Azure’s serverless platform makes it an excellent choice for many workloads.