Azure Functions Programming Model for C#
This document details the programming model for developing Azure Functions using C#. It covers triggers, bindings, and the core concepts for building serverless applications on Azure.
Understanding the Core Concepts
Azure Functions provide a serverless compute service that allows you to run small pieces of code, called "functions," without managing infrastructure. The C# programming model leverages .NET to enable rich development experiences.
Triggers and Bindings
Functions are initiated by triggers, which are events that signal a function should run. Bindings allow your function to connect to other Azure services and data sources declaratively, simplifying input and output operations.
Function Anatomy
A C# Azure Function typically consists of:
- Trigger Attribute: Defines the event that starts the function.
- Input Binding Attributes: Define data inputs to the function.
- Output Binding Attributes: Define data outputs from the function.
- Function Method: The C# method that contains your function's logic.
Developing with C#
You can develop Azure Functions with C# using various tools, including Visual Studio, Visual Studio Code, and the Azure CLI.
Trigger and Binding Attributes
The core of the programming model lies in the use of attributes. Here's an example of an HTTP-triggered function that reads a query parameter and writes to a storage queue:
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
public static class HttpTriggerExample
{
[FunctionName("HttpTriggerCSharp")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[Queue("myqueue-items", Connection = "AzureWebJobsStorage")] IAsyncCollector<string> queueCollector,
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;
if (name != null)
{
string responseMessage = $"Hello, {name}. This HTTP triggered function executed successfully. Sending message to queue.";
await queueCollector.AddAsync($"Processed: {name}");
return new OkObjectResult(responseMessage);
}
else
{
return new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
}
Common Triggers and Bindings
| Trigger/Binding | Description | Attribute Example |
|---|---|---|
| HTTP Trigger | Initiates function execution via HTTP requests. | [HttpTrigger(AuthorizationLevel.Function, "get")] |
| Timer Trigger | Executes a function on a schedule. | [TimerTrigger("0 */5 * * * *")] |
| Blob Storage Input | Reads data from Azure Blob Storage. | [Blob("container/{name}.txt")] string blobContent |
| Blob Storage Output | Writes data to Azure Blob Storage. | [Blob("output-container/{name}.txt")] out string blobOutput |
| Queue Storage Input | Reads messages from an Azure Storage Queue. | [QueueTrigger("myqueue")] string myQueueItem |
| Queue Storage Output | Writes messages to an Azure Storage Queue. | [Queue("output-queue")] out string queueOutput |
| Cosmos DB Input | Reads documents from Cosmos DB. | [CosmosDB(databaseName: "db", collectionName: "items", ConnectionStringSetting = "CosmosDBConnection")] IEnumerable<MyDocument> items |
Dependency Injection
Azure Functions in .NET support dependency injection, allowing you to inject services like configuration, logging, and custom services into your functions. This is configured in your `Startup.cs` file.
Best Practices
- Keep functions small and focused on a single task.
- Use bindings to abstract away service interactions.
- Leverage dependency injection for managing services.
- Implement proper logging for debugging and monitoring.
- Consider cold starts and optimize function initialization.